【问题标题】:How to update a global variable inside `where` clause in LINQ?如何在 LINQ 的“where”子句中更新全局变量?
【发布时间】:2019-04-26 21:19:10
【问题描述】:

我想使用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 中的 Q 代表 QUERY(读取)而不是设置值。 WHERE 也不返回值。
  • 您的实际需求是什么?
  • 你想根据你现有的列表返回一个新的列表,在哪里?
  • 您的方法有效,但谓词永远不会执行,因为您没有枚举newList。但我也建议不要在 where 谓词中产生副作用。
  • Where 过滤器。因此,如果您想要== 2 的项目,您可以这样做。也可以看看有没有结果,找到了就“告诉”。

标签: c# .net linq where extension-methods


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

    Linq 查询是惰性的,因此在您枚举 newList 之前您不会看到变化,因为您的 where 尚未执行。

    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 谓词来产生副作用,但这就是你的做法。

    【讨论】:

      猜你喜欢
      • 2012-04-12
      • 1970-01-01
      • 1970-01-01
      • 2023-03-02
      • 2022-09-22
      • 2013-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多