簡體   English   中英

選擇后跟Where在IEnumerable上進行兩次迭代嗎?

[英]Does Select followed by Where result in two iterations over the IEnumerable?

我想說

IEnumerable<int> list = new int[] { 1, 2, 3 };
List<int> filtered = list.Select(item => item * 10).Where(item => item < 20).ToList();

問題是有兩次迭代還是只有一次。

換句話說,性能相當於:

IEnumerable<int> list = new int[] { 1, 2, 3 };
List<int> filtered = new List<int>();
foreach(int item in list) {
    int newItem = item * 10;
    if(newItem < 20)
        filtered.Add(newItem);
}

當您調用.ToArray方法時,對集合執行了一次迭代,因此兩者都應該是等效的。 .Select是一個投影和.Where有一個過濾器,都表示為原始數據集上的表達式樹。

可以很容易地證明:

public class Foo: IEnumerable<int>
{
    public IEnumerator<int> GetEnumerator()
    {
        yield return 1;
        Console.WriteLine("we are at element 1");
        yield return 2;
        Console.WriteLine("we are at element 2");
        yield return 3;
        Console.WriteLine("we are at element 3");
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

class Program
{
    static void Main()
    {
        var filtered = new Foo()
            .Select(item => item * 10)
            .Where(item => item < 20)
            .ToList();
    }
}

運行時打印以下內容:

we are at element 1
we are at element 2
we are at element 3

在Linq to Objects中,WHERE和SELECT不會迭代枚舉。 調用代碼在查詢或ToList或ToArray()等上執行foreach時枚舉它。

在Linq to SQL中,沒有任何迭代。 當您執行ToList或ToArray()時,查詢將由數據庫執行。 根據查詢類型,db可以查找索引或執行表掃描。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM