如何在LINQ中的`where`子句中更新全局变量?

问题描述 投票:0回答:2

我想使用LINQWhere扩展方法过滤列表。但除了过滤之外,我还想更新Where中的全局变量。但是我不能这样做。考虑这个例子:

var list = new List<string> { "1", "2", "3", "4", "5" };

bool flag = false;
var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
});

// Here I expect flag = true, but in fact it's false
Console.Write(flag);

如你所见,我设置了flag = true,执行后仍然是值flag == false。这对我来说没有意义。你能解释一下发生了什么,以及为什么flag没有改变。还有一种方法可以改变LINQ中的全局变量吗?

c# .net linq where extension-methods
2个回答
3
投票

Linq查询是懒惰的,因此在枚举newList之前,您将看不到更改,因为您的位置尚未执行。

var list = new List<string> { "1", "2", "3", "4", "5" };

bool flag = false;
var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
});

Console.WriteLine(flag); // Flag is still false.

foreach (var item in newList) {
  // It doesn't matter what we do here, just that we enumerate the list.
}

Console.Write(flag); // Flag is now true.

foreach导致执行的位置并设置您的标志。

顺便说一句,我真的建议不要使用where谓词创建副作用,但这就是你要做的。


3
投票

只需调用ToArray()ToList()来实际执行设置flag的代码:

var newList = list.Where(item =>
{
    flag = true;
    return item == "2";
}).ToArray();

在实际枚举列表之前,不会评估传递给Where方法的谓词。

© www.soinside.com 2019 - 2024. All rights reserved.