迭代器區塊是產生有序值序列的語句區塊,透過 yield return 產生下一個值,yield break 結束迭代。可用於方法本體、運算子本體、存取子本體,前提是回傳型別為列舉器(IEnumerator/IEnumerator<T>)或可列舉(IEnumerable/IEnumerable<T>)介面。
ref/out 參數return(只能用 yield return)System.Collections.IEnumerator 及 System.Collections.Generic.IEnumerator<T>System.Collections.IEnumerable 及 System.Collections.Generic.IEnumerable<T>迭代器區塊產生值的型別稱為 yield 型別:
IEnumerator/IEnumerable → yield 型別為 objectIEnumerator<T>/IEnumerable<T> → yield 型別為 Tthis 在類別實例成員中視為值(型別為類別型別),在結構實例成員中視為變數(型別為結構型別,行為如 value 參數)。
呼叫回傳列舉器介面的迭代器方法時,不會立即執行程式碼,而是建立並回傳一個列舉器物件。該物件:
IEnumerator、IEnumerator<T>、IDisposablebefore、running、suspended、after(初始為 before)IEnumerator.Reset(拋出 NotSupportedException)| 當前狀態 | MoveNext 行為 |
|---|---|
| before | 狀態→running,初始化參數/this,從頭執行直到中斷 |
| running | 未定義行為 |
| suspended | 狀態→running,還原區域變數/參數,從上次 yield return 之後繼續執行 |
| after | 直接回傳 false |
finally 區塊不執行。finally→狀態→after→回傳 false。finally→狀態→after→例外繼續傳播。僅在 suspended 狀態有定義值(上次 MoveNext 設定)。其他狀態存取結果未定義。非 object yield 型別時,IEnumerable.Current 回傳值會轉型為 object。
before → 狀態→afterrunning → 未定義suspended → 狀態→running,執行 finally(視同最後 yield return 為 yield break)→狀態→after。若 finally 拋出例外,狀態→after 並傳播例外。after → 無作用回傳可列舉介面時,建立可列舉物件,實作 IEnumerable/IEnumerable<T>。其 GetEnumerator 回傳列舉器物件。可列舉物件也可同時實作列舉器介面(雙重角色),首次 GetEnumerator 回傳自身,後續回傳拷貝,確保各列舉器狀態獨立。