首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 2.0 規範深度解析:迭代器機制詳解(上)

     編輯:關於C語言

迭代器區塊

迭代器區塊是產生有序值序列的語句區塊,透過 yield return 產生下一個值,yield break 結束迭代。可用於方法本體、運算子本體、存取子本體,前提是回傳型別為列舉器(IEnumerator/IEnumerator<T>)或可列舉(IEnumerable/IEnumerable<T>)介面。

限制條件

  • 不可有 ref/out 參數
  • 區塊內不可使用 return(只能用 yield return)
  • 不可包含 unsafe 內容(即使外層為 unsafe)

列舉器與可列舉介面

  • 列舉器介面:System.Collections.IEnumerator 及 System.Collections.Generic.IEnumerator<T>
  • 可列舉介面:System.Collections.IEnumerable 及 System.Collections.Generic.IEnumerable<T>

Yield 型別與 this 存取

迭代器區塊產生值的型別稱為 yield 型別:

  • 回傳 IEnumerator/IEnumerable → yield 型別為 object
  • 回傳 IEnumerator<T>/IEnumerable<T> → yield 型別為 T

this 在類別實例成員中視為值(型別為類別型別),在結構實例成員中視為變數(型別為結構型別,行為如 value 參數)。

列舉器物件生命週期與狀態機

呼叫回傳列舉器介面的迭代器方法時,不會立即執行程式碼,而是建立並回傳一個列舉器物件。該物件:

  • 實作 IEnumerator、IEnumerator<T>、IDisposable
  • 以實參值拷貝初始化
  • 擁有四種狀態:before、running、suspended、after(初始為 before)
  • 通常為編譯器產生的巢狀私有類別
  • 不支援 IEnumerator.Reset(拋出 NotSupportedException)

MoveNext 狀態機邏輯

當前狀態MoveNext 行為
before狀態→running,初始化參數/this,從頭執行直到中斷
running未定義行為
suspended狀態→running,還原區域變數/參數,從上次 yield return 之後繼續執行
after直接回傳 false

執行中斷四種方式

  1. yield return:評估運算式→指派 Current→掛起(保存位置/變數)→狀態→suspended→回傳 true。finally 區塊不執行。
  2. yield break:執行相關 finally→狀態→after→回傳 false。
  3. 到達區塊結尾:狀態→after→回傳 false。
  4. 例外傳播出區塊:執行 finally→狀態→after→例外繼續傳播。

Current 屬性

僅在 suspended 狀態有定義值(上次 MoveNext 設定)。其他狀態存取結果未定義。非 object yield 型別時,IEnumerable.Current 回傳值會轉型為 object。

Dispose 方法

  • before → 狀態→after
  • running → 未定義
  • suspended → 狀態→running,執行 finally(視同最後 yield return 為 yield break)→狀態→after。若 finally 拋出例外,狀態→after 並傳播例外。
  • after → 無作用

可列舉物件

回傳可列舉介面時,建立可列舉物件,實作 IEnumerable/IEnumerable<T>。其 GetEnumerator 回傳列舉器物件。可列舉物件也可同時實作列舉器介面(雙重角色),首次 GetEnumerator 回傳自身,後續回傳拷貝,確保各列舉器狀態獨立。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved