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 {View Code5 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 yieldreturn "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 // }
上面的例子是實現了一個自定義的迭代器;實現可迭代(可以用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 之後的語句, 不會被執行!
有興趣的童鞋, 可以自己寫個例子試試。
相關推薦
C#中的yield return與Unity中的Coroutine(協程)(上)
C#中的yield return C#語法中有個特別的關鍵字yield, 它是幹什麼用的呢? 來看看專業的解釋: yield 是在迭代器塊中用於向列舉數物件提供值或發出迭代結束訊號。它的形式為下列之一:yield return <expression>;yield break 看如下例
關於C#迭代器與Unity的Coroutine
微軟的官方文件:迭代器是C#2.0中的新功能,迭代器是方法、get訪問器或運算子,使你能在類或結構體中支援foreach迭代,而不必實現整個IEnumerable介面,只需提供一個迭代器,即可遍歷類中的資料結構,當編譯器檢測到迭代器時,它將自動生成IEnumerable或IEnumerable<T&g
C#中yield return的用法示例
tel namespace ole tar spa int bsp enume con using System; using System.Collections.Generic; namespace YieldReturn { class Program
C#與unity中base64string和圖片互轉
C#: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Drawing; using
c++中的訊號與QML中的函式繫結(連結)起來 以及qml與c++互動重要筆記
signals: Q_INVOKABLE void buttonLeft(); Q_INVOKABLE void buttonRight(); Q_INVOKABLE void buttonShort(); Q_INVOKABLE void butto
c#中datetime型別與SqlServer中datetime格式的區別
一直以為c#中datetime與SqlServer中datetime類似,直到今日偶然發現兩者之間的格式是有區別的。 c#日期(圖1) 從上面的圖中我們可以看到c#的日期格式是帶星期的。 SQLServer日期(圖2) SqlServer的日期格式是不帶星期的。
C#中的委託與Java中的介面回撥
最近因為業務需求學習起了C#,對於學過Java的人來說,C#其實還是挺好懂的,基本上很多語法都是相通的。今天就談談我對C#和Java中不同的地方的理解吧。 說到Java中的介面回撥那麼就不得不提觀察者設計模式,所謂觀察者模式就是A(觀察者 Observ
Web服務器之Tomcat的相關說明(Web訪問中的角色與協議問題和JavaWeb項目的程序結構問題)
b/s架構 c/s架構 context.xml說明 server.xml說明 javaweb項目的程序結構 1、C/S架構和B/S架構的概念:a、C/S架構:- C/S,Client/Server,客戶端/服務器,客戶端需要安裝專用的客戶端軟件。客戶端是針對某以具體業務專門開發的軟件。-
使用C#的Conditional特性與Unity編輯器宏命令做條件編譯
運行時 符號 unit log edit ext 通過 space 編譯 概要 在傳統的C#項目中,用Conditional特性做條件編譯時,需要在Visual Studio中項目的屬性裏添加上條件編譯符號,用法參考這篇文章。 而在Unity項目中,條件編譯符號需要在Uni
python中的__new__與__init__,新式類和經典類(2.x)
類型 pytho 圖片 pla object pri lba 版本 其它 在python2.x中,從object繼承得來的類稱為新式類(如class A(object))不從object繼承得來的類稱為經典類(如class A()) 新式類跟經典類的差別主要是以下幾點:
javaScript中的onclick與jquery中的click區別
mce 上下 要點 let 怎樣 報錯 ron n) 屬性 來來來,先看一個例子: html部分,定義幾個按鈕 <div class="carousel-btn"> <button class="btn"></button>
虛擬機器下ubuntu中檔案實現與windows中檔案共享
第一步 在Ubuntu選單上選擇VM->install VMware tools。然後出現VMware tools的安裝壓縮包檔案VMwareTools-9.2.0-799703.tar.gz。 第二步 可以先將該壓縮檔案複製到主資料夾下,然後解壓tar.gz
Python中“i+=i與i=i+i”的區別梳理:(引用、記憶體、可變引數、不可變引數)
Python中“i+=i與i=i+i”的區別梳理 一、 "i+=i"執行時資料記憶體的變化 當num+=num執行時,num原引用的記憶體空間中,根據空間中儲存的引數的資料型別是否為可變型別而進行變化,***可變的引數資料型別***有:列表、字典;***不可變引
當ROS中的cv2與anaconda3中的cv2衝突時的解決辦法
今天心血來潮, 想用Anaconda3中的Python3.6.4跑一個opencv小例子, 結果出人意料,出現了ROS中的/opt/ros/kinetic/lib/python2.7/dist-packages/cv2.so檔案, 顯然這個是行不通的嘛, 然後我
獲取json中的key與value中的方法
String res = "{"_index":"k12oos","_type":"exercise","_id":"-0WtGG1FhQSmqIQhKU8pMg","_version":2,"found":true,"_source":{"code":"1009430255","stageId":"go2L
JS中的onload與jQuery中的ready區別
jQuery的執行機制(onload與ready的區別) 結論得出前自行測試: 為了測試是否真如所說的那樣,所以在頁面插入了20000張照片,照片數量少得不出什麼結論,所以改用console.log
Object中的tostring與Array中的tostring的區別?
Object 類的 toString 方法返回一個字串,該字串由類名(物件是該類的一個例項)、at 標記符“@”和此物件雜湊碼的無符號十六進位制表示組成。Arrays的toString方法是返回指定陣列內容的字串表示形式。 兩者是重名函式關係,沒有複寫。 從意會的角度講,這就好比羊喝水和你喝水一
ES5中的var與ES6中的let,const的區別
1、ES5中使用var來宣告變數,會產生作用域提升的問題。例: var a=1; function scope(){ console.log(a); var a=2; } scope(); //得到的結果既不是1也不是2,是undefined
jface databinding:使用CheckboxTableViewer實現表中(Set)物件與CheckTable中選中條目資料繫結
上一篇博文《jface databinding:可多選的widget List元件selection專案與java.util.List物件的雙向資料繫結》講述瞭如何實現List元件的多選項與List資料繫結的問題。 實際使用中覺得用List元件來給使用者做多選
獲取瀏覽器語言的完美方案。(各瀏覽器對 navigator 物件中幾個與語言相關的屬性的返回值存在差異)
標準參考 無 問題描述 各瀏覽器對 navigator 物件中幾個與語言相關的屬性(language、userLanguage、browserLanguage、 systemLanguage)的返回值存在很大的差異。 造成的影響 由於不同瀏覽器對這幾個屬性的返回值有很