2016-01-24 42 views
0

爲什麼每次循環IEnumerable而不是在初始Select期間,都會創建實例?爲什麼選擇新實例只能在枚舉上構造?

this.bars = this.values.Select(x => new Bar(x)); 

我期望通過價值循環,選擇一個新的酒吧,然後有,但已經測試了它,它在那一刻產生沒有任何實例,而不是通過它創建新實例每次時間循環。

private IEnumerable<Bar> bars; 

酒吧現場被聲明爲IEnuermable,所以我不明白它如何能夠保持任何形式的功能或關閉。

  • 這是預期的行爲,如果是這樣,爲什麼?
  • 我如何用Linq做這件事,但是在那裏和那裏創建一組新的實例?

控制檯測試應用程序的完整的源:

namespace LINQ_Test 
{ 
    using System.Collections.Generic; 
    using System.Diagnostics; 
    using System.Linq; 

    public class Bar 
    { 
     private int value; 

     public Bar(int value) 
     { 
      this.value = value; 
      Debug.WriteLine("CTOR: " + value); 
     } 
    } 

    public class Foo 
    { 
     private IEnumerable<Bar> bars; 
     private IEnumerable<int> values = new int[] { 0, 1234, -1 }; 

     public void LoopValues() 
     { 
      Debug.WriteLine("Looping through bars 3 times:"); 
      for (int loop = 0; loop < 3; loop++) 
      { 
       foreach (Bar bar in this.bars) 
       { 
       } 
       Debug.WriteLine(" (next loop)"); 
      } 
      Debug.WriteLine("-\n"); 
     } 

     public void SetupValues() 
     { 
      Debug.WriteLine("Settings up bars:"); 
      this.bars = this.values.Select(x => new Bar(x)); 
      Debug.WriteLine("-\n"); 
     } 
    } 

    internal class Program 
    { 
     private static void Main(string[] args) 
     { 
      Foo foo = new Foo(); 
      foo.SetupValues(); 
      foo.LoopValues(); 
     } 
    } 
} 

APP輸出:

Settings up bars: 
- 

Looping through bars 3 times: 
CTOR: 0 
CTOR: 1234 
CTOR: -1 
    (next loop) 
CTOR: 0 
CTOR: 1234 
CTOR: -1 
    (next loop) 
CTOR: 0 
CTOR: 1234 
CTOR: -1 
    (next loop) 
- 
+3

是的,這是預期的行爲。你可以使用'this.values.Select(x => new Bar(x))枚舉一次。ToList();''我認爲在這種情況下,ReSharper甚至會告訴你'IEnumerable可能多枚舉'。 –

+1

這是預期的行爲,谷歌Linq懶惰評估。 –

+0

這必須是一個常見問題... –

回答

2

是的,這是預期的行爲,並在IEnumerable#Select documentation記錄。從該鏈接開始:

該方法通過使用延遲執行來實現。即時返回值是存儲執行操作所需的所有信息的對象。直到通過直接調用其GetEnumerator方法或使用Visual C#中的foreach或Visual Basic中的For Each來枚舉對象,纔會執行此方法表示的查詢。

如果您希望立即完成,可以立即列舉它,也許用ToList

+1

啊,就這樣!我明白現在發生了什麼,謝謝你。 – Octopoid