lambda表达式内的赋值

本文关键字:赋值 表达式 lambda | 更新日期: 2023-09-27 17:50:48

我做了一个扩展,在ObservableCollection上添加ForEach()方法:

public static void ForEach<T>(this ObservableCollection<T> enumerable, Action<T> action)
{
    foreach (var item in enumerable)
        action(item);
}

当我使用它时,像这样:

private bool Bar(int i)
{
    return i % 2 == 1;
}
private void Foo()
{
    Boolean ok = true;
    ObservableCollection<int> oc = new ObservableCollection<int> { 1, 2, 3, 4 };
    oc.ForEach(i => ok &= Bar(i));
    //ok is now false
}

我不明白ok布尔值是如何接受action(item)执行的Bar()方法返回的值的?

lambda表达式内的赋值

Lambdas被允许修改在其代码体内的代码范围内的变量。对于这类代码,您需要非常小心,因为您并不总是能够完全控制执行lambdas的时间。

例如,如果你给一个lambda添加了一个赋值,并将其传递给一个延迟执行的方法,那么该lambda的副作用(即赋值)在该lambda的代码实际执行之前是不可见的。

下面是一个例子:

bool ok = true;
IEnumerable<int> res = new[] {1, 2, 3}.Where(i => ok &= (i == 2));
// ok is true here
IList<int> listRes = res.ToList();
// ok is false here

如果运行这段代码,即使源列表的第一项会触发将false赋值给ok变量,ok仍然是true。但是,在枚举res之前,这种情况不会发生。

您正在应用&=,它将使用前一个值ok和每个结果(因为ok不是单个循环迭代的局部值,它在循环外声明)。换句话说,

作为条件只对两个值(1和3)为真

ok = true &&假的,,真的,,假