我有此代码,该代码应该返回一个值类型,在每个步骤中应用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
避免循环 - 您只是隐藏它,而这样做的过程使您的代码过于复杂,以至于您不这样做。再了解它。
如果您真的可以使用Linq,则可以使用Aggregate
:
private static T Transformed<T>( T x, params Func<T, T>[] steps ) where T : struct
{
return steps?.Aggregate( x, ( accum, f ) => f( accum ) ) ?? x;
}
我通常不会发现汇总特别可读,但我认为值得一提的是。