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

C# 2.0 新特性深度解析(五):迭代器編譯器實作與狀態機機制

     編輯:關於C語言

迭代器編譯器生成架構

含 `yield return` 的方法/屬性,編譯器生成巢狀類別實作 `IEnumerator`:


// 原始碼
public IEnumerator GetEnumerator()
{
    yield return "New York";
    yield return "Paris";
    yield return "London";
}

// 編譯器生成偽代碼
public class MyCollection : IEnumerable
{
    public IEnumerator GetEnumerator()
    {
        var impl = new GetEnumerator$0003__IEnumeratorImpl();
        impl.<this> = this;
        return impl;
    }

    private class GetEnumerator$0003__IEnumeratorImpl : IEnumerator
    {
        public MyCollection <this>;
        string $_current;
        // 狀態機欄位...
        public string Current => $_current;
        public bool MoveNext() { /* 狀態機邏輯 */ }
        public void Dispose() { /* 清理 */ }
    }
}

狀態機運作原理

  • 每次 `foreach` 呼叫 `GetEnumerator()` 建立新迭代器實例(狀態重置)。
  • `MoveNext()` 從上一個 `yield return` 繼續執行,透過整數狀態欄位跳轉。
  • 多個 `yield return` 依出現順序串聯成狀態遷移圖。
  • 迭代器物件不跨 `foreach` 保持狀態,重新 `foreach` 安全。
  • 因此 `IEnumerable` 無 `Reset()` 方法(由新實例替代)。

關鍵欄位

  • `<this>`:外部類別參考,存取成員用。
  • `$_current`:當前產生值。
  • 狀態整數:追蹤執行進度(-1=未開始, 0=首個yield, 1=第二個...)。
  • `Dispose()`:釋放非托管資源(如檔案控制碼),`foreach` 結束自動呼叫。

實務啟示

  • 理解狀態機有助診斷 `yield` 在 `try/finally` 中的行為(`finally` 在 `Dispose` 執行)。
  • 避免在緊迴圈中頻繁建立迭代器(如逐行讀取大檔),改用手寫 `IEnumerator` 複用實例。
  • 編譯器生成名稱含 `$`、`<>` 非法識別碼,反射取得時需過濾。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved