下面的 LINQ 语句是如何工作的?

下面的 LINQ语句是如何工作的?

这是我的代码:

var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0);
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}

输出: 2, 4, 6, 8

为什么不是 2, 4, 6

4429 次浏览

由于 延期执行,输出为 2,4,6,8

当查询变量 而不是在创建查询变量时迭代。 这就是所谓的延迟执行。

—— Suprotim Agarwal,“ LINQ 中的延迟与即时查询执行”

还有另一种执行方式称为 即时查询执行,它对缓存查询结果很有用:

若要强制立即执行不产生单例值的查询,可以对查询或查询变量调用 ToList(), ToDictionary(), ToArray(), Count(), Average()Max()方法。这些被称为转换运算符,它允许您对结果进行复制/快照,并且访问次数可以是您想要的,而不需要重新执行查询。

如果希望输出为 2,4,6,请使用 .ToList():

var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0).ToList();
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}

这是由于延迟执行造成的,这意味着表达式的计算只有在某处需要时才会执行。如果数据太大,这将提高性能。

原因是 lambda 表达式的延迟执行。当您开始在 foreach 循环中迭代时,将执行查询。

你得到这个结果是因为延迟执行,这意味着在结果第一次被访问之前,它实际上并没有被计算。

为了更清楚地说明,只需在代码片段末尾的列表中添加10,然后再次打印,就不会得到10的输出

     var list = new List<int>{1,2,4,5,6};
var even = list.Where(m => m%2 == 0).Tolist();
list.Add(8);
foreach (var i in even)
{
Console.WriteLine(i);
}
//new*
list.Add(10);
foreach (var i in even)
{
Console.WriteLine(i);
}

当使用从 LINQ 获得的 IEnumable < > 时,只创建一个 Enumerator 类,并且只有在某次遍历中使用它时才开始迭代。