2014-10-30 147 views
1

我是想更好地瞭解LINQ的功能組成,該效果做額外的傳球,我寫這樣的代碼:的LINQ採取措施,通過收集

var x = Enumerable.Range(1, 10); 

var result = x.Select(AddFive) 
       .Where(FilterEvens) 
       .Take(1); 

result.ToList(); 

凡AddFive和FilterEvens方法定義如下:

int AddFive(int n) 
{ 
    Console.WriteLine("Adding five"); 
    return n+5; 
} 

bool FilterEvens(int n) 
{ 
    Console.WriteLine("Filtering evens"); 
    return n%2 == 0; 
} 

如果我拿1並運行它,我得到以下結果這正是我所期望的:

新增五個
過濾找齊

如果我嘗試採取2或5然而,我得到:

新增五個
過濾找齊
新增五個
過濾找齊
新增五
Filtering evens

和:

新增五個
過濾找齊
新增五個
過濾找齊
新增五個
過濾找齊
新增五個
過濾找齊
新增五個
過濾找齊
添加五個
過濾找齊
新增五個
過濾找齊
新增五個
過濾找齊
新增五個
過濾找齊

換句話說,它看起來像採取進一步去比它需要在集合。這是一個錯誤嗎? (我猜這不是)。如果不是這樣,那麼爲什麼以這種方式實現它有一些很好的理由嗎?

+1

它只是預期。試着在'.Range(2,10)'上拍'(1)',你會看到兩個項目被投影和過濾。:)在所有先前的轉換之後,'Take'將會像從序列*中指定的一樣多的項目*。 – 2014-10-30 15:03:26

回答

4

Take不會繼續。它會一直迭代,直到找到想要的數字爲止。由於您有一個過濾條件,並不是所有的數字都會被返回,因爲其中一些條件不符合條件。所以,您會看到每個由Select投影的數字的消息並通過Where.

例如在Take(2)情況:

Select returns 6 to where - it's returned 
Select returns 7 to where - not returned 
Select returns 8 to where - returned 

這就是爲什麼你看到消息三次

+0

哦,當然!謝謝! – aj100 2014-10-30 15:15:21