4

我有一个List<String> myList.

我想获取此列表中符合某些条件的前 10 个项目(例如,假设.Contains("a"))。

我有:

Var results = myList.Where(o=>o.Contains("a")).Take(10);

哪个工作正常,但 LINQ 是否执行了Where检索所有符合此条件的项目,然后只取了前 10 个?或者这是否会以考虑整个 LINQ 语句的方式进行编译(即它将执行Where但只执行到 10 个项目)?

4

3 回答 3

8

LINQ 使用惰性求值。当您执行以下行时:

var results = myList.Where(o=>o.Contains("a")).Take(10);

没发生什么事。仅构建查询。当您枚举results, (例如使用 aforeach或 a ToList())时,WhereandTake将应用于myList:Where将根据需要执行,直到true找到最多 10 个值。

于 2013-10-24T13:30:57.703 回答
4

Where 语句返回一个等待枚举的 IEnumerable。Where 逻辑的执行会延迟,直到您“询问”IEnumerable 的下一个值。

Take(10) 语句就是这样做的 - 要求它为 Where 条件提供“下一个匹配项”。这将执行 10 次,然后完成。但是当然,出于同样的原因,直到您枚举最终返回值(在您的情况下为结果),才会真正执行 Take(10) 语句的逻辑。

所以是的,它有点优化,但可能不像你想象的那样。

于 2013-10-24T13:30:41.860 回答
3

看下面的代码:

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”之后的字符串没有被评估)。

于 2013-10-24T13:47:07.180 回答