C#中yield return用法

1.yield關鍵字用於遍歷循環中,yield return用於返回IEnumerable<T>,yield break用於終止循環遍歷

不使用yield return的實現
測試

   
   
   
   
   
static IEnumerable<int> FilterWithoutYield(){ List<int> result = new List<int>(); foreach (int i in GetInitialData()) { if (i > 2) { result.Add(i); //這裏的add就把結果都給了result,返回一個List<int>類型的result對象,因此這裏返回的結果result是List<int>類型,會轉化爲IEnumerable<int>類型 } } return result;}
使用yeild return實現
    
    
    
    
    
static IEnumerable<int> FilterWithYield(){ foreach (int i in GetInitialData()) { if (i > 2) { yield return i; } } yield break; Console.WriteLine("這裏的代碼不執行");}
客戶端調用的代碼是相同的
    
    
    
    
    
static void Main(string[] args){ foreach (var item in FilterWithYield()) { Console.WriteLine(item); } Console.ReadKey(); }
使用這個代碼測試LINQ表達式,結果發現:方法的類不是IEnumerable<T>類型,只有方法的返回值是IEnumerable<T>,因此只能對方法的返回值使用LINQ
因此使用LINQ就有兩個條件:
1.對類來講,這個類繼承了IEnumerable<T>,就要實現IEnumerator GetNumerator方法
2.對方法來講,這個方法返回了IEnumerable<T>接口的類型
雖然2種方法的輸出結果是同樣的,但運做過程迥然不一樣。第一種方法,是把結果集所有加載到內存中再遍歷;第二種方法,客戶端每調用一次,yield return就返回一個值給客戶端,是"按需供給"。

第一種方法,客戶端調用過程大體爲:spa

使用yield return,客戶端調用過程大體爲:.net

使用yield return爲何能保證每次循環遍歷的時候從前一次中止的地方開始執行呢?code

--由於,編譯器會生成一個狀態機來維護迭代器的狀態。htm

簡單地說,當但願獲取一個IEnumerable<T>類型的集合,而不想把數據一次性加載到內存,就能夠考慮使用yield return實現"按需供給"。對象



實現一個IEnumerable接口的代碼

    
    
    
    
    
public class Stack : IEnumerable { int[] items = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; public IEnumerator GetEnumerator() { for (int i = 0; i < items.Length; i++) { yield return items[i]; // return返回的是IEnumerator集合對象,也就是說類中自己就有了一個 //IEnumerator對象,Foreach遍歷的時候,也遍歷的是這個IEnumerator對象,因此直接寫foreach(var i in ss)就能夠了,底層幫助完成其餘代碼 } } }





 


相關文章
相關標籤/搜索