我想使用LINQ
和Where
扩展方法过滤列表。但除了过滤之外,我还想更新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
中的全局变量吗?
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谓词创建副作用,但这就是你要做的。
只需调用ToArray()
或ToList()
来实际执行设置flag
的代码:
var newList = list.Where(item =>
{
flag = true;
return item == "2";
}).ToArray();
在实际枚举列表之前,不会评估传递给Where
方法的谓词。