1. 程式人生 > >C# yield return用法

C# yield return用法

理解 ring ref 所有 每次 () r12 停止 image

本文實例講述了C#中yield return用法,並且對比了使用yield return與不使用yield return的情況,以便讀者更好的進行理解。具體如下:

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

有這樣的一個int類型的集合:

?
1 2 3 4 static List<int> GetInitialData() { return new List<int>(){1,2,3,4}; }

需要打印出所有值大於2的元素。

不使用yield return的實現

?
1 2 3 4 5 6 7 8 9 10 11 12 static IEnumerable<int> FilterWithoutYield() { List<int> result = new List<int>(); foreach (int i in GetInitialData()) { if (i > 2) { result.Add(i); } } return result; }

客戶端調用:

?
1 2 3 4 5 6 7 8 static void Main(string[] args) { foreach (var item in FilterWithoutYield()) { Console.WriteLine(item); } Console.ReadKey(); }

輸出結果:3,4

使用yeild return實現

?
1 2 3 4 5 6 7 8 9 10 11 12 static IEnumerable<int> FilterWithYield() { foreach (int i in GetInitialData())
{ if (i > 2) { yield return i; } } yield break; Console.WriteLine("這裏的代碼不執行"); }

客戶端調用:

?
1 2 3 4 5 6 7 8 static void Main(string[] args) { foreach (var item in FilterWithYield()) { Console.WriteLine(item); } Console.ReadKey(); }

輸出結果:3,4

總結:

通過單步調試發現:

雖然2種方法的輸出結果是一樣的,但運作過程迥然不同。第一種方法,是把結果集全部加載到內存中再遍歷;第二種方法,客戶端每調用一次,yield return就返回一個值給客戶端,是"按需供給"。

第一種方法,客戶端調用過程大致為:

技術分享

使用yield return,客戶端調用過程大致為:

技術分享

使用yield return為什麽能保證每次循環遍歷的時候從前一次停止的地方開始執行呢?

--因為,編譯器會生成一個狀態機來維護叠代器的狀態。

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

希望本文所述對大家的C#程序設計有所幫助。

C# yield return用法