C# yield


  C#中的yield可以應用在一個可迭代的方法中,我們必須真正理解此關鍵詞,才能將它正確的應用到實際生產中。為了說明yield會出現讓我們迷惑的結果,下面先定義一個MyObject類:

1     class MyObject
2     {
3        public int Value{get;set;}
4     }

  MyObject類用於存放一個值,下面定義一個IEnumerable<MyObject>的方法:

1 IEnumerable<MyObject> GetYieldObjects()
2 {
3     for (int i = 0; i < 10; i++)
4     {
5         Console.WriteLine("GetObjects() i="+i.ToString());
6         yield return new MyObject() { Value = i };
7     }
8 }

   方法中用yield return返回實例化的MyObject對象,為了便於記錄GetYieldObjects()方法實際調用的過程,這里用Console.WriteLine來記錄每次調用的過程。下面聲明一個objects對象,然后進行第一次迭代,在第一次迭代過程中,對每個迭代項目的值進行+10處理,然后進行第2此迭代,看看是否會將處理后的值進行輸出:

 1 //此時不調用GetObjects()的內部循環
 2 var objects = GetYieldObjects();
 3 //每次迭代會調用GetObjects()對應i的內容
 4 foreach (var item in objects)
 5 {
 6     Console.WriteLine("1 foreach (var item in objects) item.Value=" + item.Value.ToString());//0..9
 7     item.Value += 10;
 8 }
 9 //每次迭代會調用GetObjects()對應i的內容
10 foreach (var item in objects)
11 {
12     Console.WriteLine("2 foreach (var item in objects) item.Value=" + item.Value.ToString());//0..9
13     Console.WriteLine(item.Value.ToString());//0..9
14 }

   在第2次迭代時,輸出的還是0到9,並不是10到19.請看下面的迭代過程:

當第一次迭代時候,每次迭代會調用GetObject()方法中的yield return語句,而不是在var objects=GetObjects()進行實例化。當yield取到一個MyObject對象后立刻返回給迭代器,並將其值進行輸出,然后繼續調用GetObjects方法中的yield return語句,

因此每次循環時,實際上都是一個新的對象。如下圖所示:

 

   當然如果將上面的代碼稍作修改,用objects=GetYieldObjects().ToArray()的話,那么第二次輸出的就是10到19:

 1 objects = GetYieldObjects().ToArray();
 2 foreach (var item in objects)
 3 {
 4     item.Value += 10;
 5 }
 6 
 7 foreach (var item in objects)
 8 {
 9     Console.WriteLine(item.Value.ToString());//10..19
10 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM