C# yield return 用法與解析

C# yield return 用法與解析spa

本文參考自:http://www.jb51.net/article/54810.htm.net

 

 當初沒有認真理解 yield 這個關鍵字,如今又遇到了依舊不理解,爲了之後再也不爲了 yield 困惑,決定好好研究一下 yield 的用法與意義:調試

yield 從字面上理解有「退位,屈服」的意思,轉一下彎就理解成「權限轉移」,也就是將控制權交給別人,在這裏就是把集合裏知足條件(若是沒有過濾條件,就是全體)的個體的操做轉移給另外一個對象。code

    class Program { static void Main(string[] args) { foreach (var item in FilterWithoutYield) { Console.WriteLine(item); } Console.ReadKey(); } //申明屬性,定義數據來源
        public static List<int> Data { get { return new List<int>(){1,2,3,4,5,6,7,8}; } } //申明屬性,過濾器(不適用yield)
        public static IEnumerable<int> FilterWithoutYield { get { var result = new List<int>(); foreach (var i in Data) { if (i > 4) result.Add(i); } return result; } } }

能夠看到若是不用yield,要返回大於4的全部的樹,就要到另外一個集合。而用yield的狀況下就沒必要如此麻煩了:htm

        //申明屬性,過濾器(使用yield)
        public static IEnumerable<int> FilterWithoutYield { get { foreach (var i in Data) { if (i > 4) yield return i; } } }

爲何會這樣呢?對象

經過單步調試發現:blog

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

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

使用yield return,客戶端調用過程大體爲:編譯器

 

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

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

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

相關文章
相關標籤/搜索