程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#中的yield return與Unity中的Coroutine(協程)(上),

C#中的yield return與Unity中的Coroutine(協程)(上),

編輯:C#入門知識

C#中的yield return與Unity中的Coroutine(協程)(上),


C#中的yield return

C#語法中有個特別的關鍵字yield, 它是干什麼用的呢?

來看看專業的解釋:

yield 是在迭代器塊中用於向枚舉數對象提供值或發出迭代結束信號。它的形式為下列之一:
yield return <expression>;
yield break

 

看如下例子:

 

1 1 public class CustomCollection :IEnumerable { 2 2 3 3 public static void Main (string[] args) 4 4 { 5 5 CustomCollection cc = new CustomCollection (); 6 6 7 7 foreach (String word in cc) { 8 8 Console.WriteLine ("word:" +word); 9 9 } 10 10 } 11 11 12 12 public IEnumerator GetEnumerator(){ 13 13 14 14 yield return "Hello"; 15 15 yield return "Boys"; 16 16 yield return "And"; 17 17 yield return "Girls"; 18 18 //return new HelloBoyGirls(); 19 19 20 20 } 21 21 } 22 22 23 23 // public class HelloBoyGirls: IEnumerator { 24 24 // private int cusor = -1; 25 25 // private String[] words = {"Hello", "Boys", "And", "Girls"}; 26 26 // 27 27 // public bool MoveNext () 28 28 // { 29 29 // cusor++; 30 30 // return cusor < words.Length; 31 31 // } 32 32 // 33 33 // public void Reset () 34 34 // { 35 35 // cusor = 0; 36 36 // } 37 37 // 38 38 // public object Current { 39 39 // get { 40 40 // return words [cusor]; 41 41 // } 42 42 // } 43 43 // } View Code

 

 

 

上面的例子是實現了一個自定義的迭代器;實現可迭代(可以用foreach)的數據集合,必須實現GetEmumerator()方法,返回實現了IEmumerator的對象實例。

完成這個, 有兩種方法,一種是用上面注釋掉的代碼,一種是用yield return. yield return 需要配合IEmumerator進行使用, 在外部foreach循環中,它會執行GetEmumerator()方法,遇到yield return, 做了如下兩件事情:

1.記錄下當前執行到的代碼位置

2. 將代碼控制權返回到外部, yield return 後面的值, 作為迭代的當前值。

當執行下一個循環, 從剛才記錄的代碼位置後面, 開始繼續執行代碼。

簡單地說, yield return 就是實現IEmumerator的超級簡化版, 是不是很簡單?

 

那麼問題又來了, yield return 是如何決定循環該結束,yield return 之後的代碼, 什麼時候執行呢?

把上面的例子改造一下, 不要用方便的foreach了, 用while 循環自己控制:

1 public class CustomCollection :IEnumerable { 2 3 public static void Main (string[] args) 4 { 5 CustomCollection cc = new CustomCollection (); 6 7 IEnumerator enumerator = cc.GetEnumerator (); 8 while (true) { 9 bool canMoveNext = enumerator.MoveNext (); 10 Console.WriteLine ("canMoveNext:" +canMoveNext); 11 if (!canMoveNext) 12 break; 13 Object obj = enumerator.Current; 14 Console.WriteLine ("current obj:" +obj); 15 } 16 // foreach (String word in cc) { 17 // Console.WriteLine ("word:" +word); 18 // } 19 Console.WriteLine ("Main End."); 20 21 } 22 23 public IEnumerator GetEnumerator(){ 24 25 yield return "Hello"; 26 yield return "Boys"; 27 yield return "And"; 28 yield return "Girls"; 29 30 Console.WriteLine ("After all yield returns."); 31 //return new HelloBoyGirls(); 32 33 } 34 } View Code

 

運行代碼, 結果是:

canMoveNext:True
current obj:Hello
canMoveNext:True
current obj:Boys
canMoveNext:True
current obj:And
canMoveNext:True
current obj:Girls
After all yield returns.
canMoveNext:False
Main End.

說明, 在GetEmumerator()中, 只有yield return 語句, 外部調用MoveNext()都為true, current就是yield return後面的對象

除了yield return, 還有yield break; yield break 的作用是, 停止循環, MoveNext()為false, yield break 之後的語句, 不會被執行!

有興趣的童鞋, 可以自己寫個例子試試。

 

  

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved