c# - Where() 的意外结果

标签 c# linq

我有这段代码,它应该返回一个值类型,在每一步应用 steps 中指定的转换。

private static T Transformed<T>(T x, params Func<T, T>[] steps) where T : struct
{
     if ((steps?.Length ?? 0) == 0)
     {
        return x;
     }

     var reallyEmpty = steps.Where(f => (x = f(x)).Equals(int.MinValue));
     return x;
}

我只需要 Where 扩展来完成每个步骤而不使用循环,因此我使用了一个可能永远不会为真的条件 (Equals(int.MinValue)). 但是,如果我有此调用代码,我会得到 5 而不是 15,这是我所期望的。

int res1 = Transformed(5, x => x * 2, x => x + 5);
Console.WriteLine(res1);

我的问题是为什么? Where 不会遍历每个元素并检查它吗?

最佳答案

Where 是惰性求值的——你永远不会使用它的结果,所以谓词永远不会被求值。

可以通过计算结果或类似方式来强制迭代:

var ignored  steps.Where(f => (x = f(x)).Equals(int.MinValue)).Count();

...但是循环自己会更清楚:

foreach (var step in steps) 
{
    x = step(x);
}

毕竟,您并不是真的通过使用 Where 来避免循环 - 您只是隐藏了它,这样做会使您的代码过于复杂你不再理解它的程度。

关于c# - Where() 的意外结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42371547/

相关文章:

C#:(float) (x/y) 和 x/(float) y 之间有区别吗?

c# - NHibernate 将缓存实体重新附加到不同 session 的正确方法

c# - DropDownListForModel 无法添加 HTML 属性

c# - EF Core - 在运行时向数据库添加新表

.net - 如何在 Matlab 中迭代 C# IEnumerable?

linq - 多对多 EF LINQ

c# - 如何使用linq删除项目

c# - 使用资源文件的多语言支持

c# - 在ForEach语句中使用linq

linq - 如何使用流利的 linq 获取当前不在映射表中的对象