了解LINQ的Where / Take的基本原理

时间:2013-10-24 13:19:27

标签: c# performance linq loops take

我有List<String> myList

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

我有:

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

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

3 个答案:

答案 0 :(得分:8)

LINQ使用延迟评估。当您执行以下行时:

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

什么都没发生。仅构建查询。当您枚举results时(例如,使用foreachToList()),WhereTake将应用于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”之后的字符串未被评估)。

相关问题