我有List<String> myList
。
我想在此列表中的前10个项目符合某些条件(例如,假设为.Contains("a")
)。
我有:
Var results = myList.Where(o=>o.Contains("a")).Take(10);
哪个工作正常,但LINQ执行了Where
来检索符合此条件的所有项目,而然后只采用了前10个项目?或者这是否会以考虑整个LINQ语句的方式进行编译(即它将执行Where
,但只能达到10项)?
答案 0 :(得分:8)
LINQ使用延迟评估。当您执行以下行时:
var results = myList.Where(o=>o.Contains("a")).Take(10);
什么都没发生。仅构建查询。当您枚举results
时(例如,使用foreach
或ToList()
),Where
和Take
将应用于myList
:{ {1}}将根据需要执行,直到找到最多10 Where
个值。
答案 1 :(得分:4)
Where语句返回一个等待枚举的IEnumerable。 Where逻辑的执行被延迟,直到你'询问'IEnumerable的下一个值。
Take(10)语句就是这样 - 询问它的Where条件的'下一个匹配'。这将执行10次,然后完成。但是,当然,出于同样的原因,Take(10)语句的逻辑在您枚举最终返回值(结果,在您的情况下)之前不会实际执行。
所以是的,它有点优化,但可能不像你想象的那样。
答案 2 :(得分:2)
请看下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
public class Test {
public static void Main(String[] args) {
var l = new List<String>() { "a", "ab", "b", "bb", "bc", "ba", "c", "ca", "cc" };
foreach (var s in l.Where(e => { Console.WriteLine(e); return e.Contains("a"); }).Take(3)) {
Console.WriteLine("loop: {0}", s);
}
}
}
输出结果为:
a
loop: a
ab
loop: ab
b
bb
bc
ba
loop: ba
因此,您可以看到它已经过优化(“C”之后的字符串未被评估)。