流模式(延迟评估)与非流模式(急切评估)
在使用延迟执行的 LINQ 方法中,有些需要一次评估一个值。以下代码:
var lst = new List<int>() {3, 5, 1, 2};
var streamingQuery = lst.Select(x => {
Console.WriteLine(x);
return x;
});
foreach (var i in streamingQuery) {
Console.WriteLine($"foreach iteration value: {i}");
}
将输出:
3
foreach 迭代值:3
5
foreach 迭代值:5
1
foreach 迭代值:1
2
foreach 迭代值:2
因为传递给 Select
的函数是在 foreach
的每次迭代中计算的。这称为流模式或惰性评估 。
其他 LINQ 方法 - 排序和分组运算符 - 需要评估所有值,然后才能返回任何值:
var nonStreamingQuery = lst.OrderBy(x => {
Console.WriteLine(x);
return x;
});
foreach (var i in nonStreamingQuery) {
Console.WriteLine($"foreach iteration value: {i}");
}
将输出:
3
5
1
2
foreach 迭代值:1
foreach 迭代值:2
foreach 迭代值:3
foreach 迭代值:5
在这种情况下,因为必须以递增的顺序为 foreach
生成值,所以必须首先评估所有元素,以便确定哪个是最小的,哪个是下一个最小的,依此类推。这称为非流模式或急切评估 。