假设我们有list.Where(p => p.Number> n).Select(p => p.Name).Where(n => n.StartsWith(a)).ToList();这将是一次通过算法还是3次通过?
解决方法
由于LINQ流式传输数据的方式,它将在一次传递中构建列表.
例如,拿这个:
var query = list.Where(p => p.Number > n);
这本身并没有查看列表中的任何元素.相反,它会记住您正在查看的列表,当您开始迭代查询时,每次请求下一个元素时,它将依次检查列表中的元素,直到找到匹配为止 – 然后停止.例如:
using (var iterator = query.GetEnumerator()) { iterator.MoveNext(); // This will look for the first match Console.WriteLine(iterator.Current); iterator.MoveNext(); // This will continue from just after the first match }
每个操作都以这种方式工作 – 所以当你得到时:
var query = list.Where(...) .Select(...) .Where(...);
…当你要求查询中的第一个项目时,它会链接回来(所以最后一个Where会询问Select的结果,它将询问第一个Where的结果,它将询问列表)并继续运行直到它有一个结果.然后当你要求下一个项目时,会询问下一个项目的选择结果等.
ToList构建List< T>从它的来源中的所有项目,立即 – 它在这个意义上渴望(而不是在这里懒惰的其他操作符).但原始列表本身仍将只迭代一次.
有关LINQ to Objects如何工作的更多细节 – 包括示例实现 – 您可能想要阅读我的Edulinq blog series.