意外的结果(where()



我有此代码,该代码应该返回一个值类型,在每个步骤中应用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;
}

我通常不会发现汇总特别可读,但我认为值得一提的是。

最新更新