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

C# foreach 迴圈深度解析:語法、集合介面契約、唯讀語意與效能

     編輯:關於C#

語法結構


foreach (Type variable in enumerable)
    statement;

// 等價展開 (簡化版)
IEnumerator enumerator = enumerable.GetEnumerator();
try {
    while (enumerator.MoveNext()) {
        Type variable = (Type)enumerator.Current;
        statement;
    }
}
finally {
    (enumerator as IDisposable)?.Dispose();
}

集合型別契約:鴨子類型

C# foreach 不要求實作 IEnumerable,只需符合模式:

這叫「鴨子類型」:長得像列舉器就能用,不必繼承介面。但實作 IEnumerable/IEnumerable<T> 可獲得 LINQ、標準庫互通性。

迴圈變數唯讀語意


foreach (var item in list)
{
    item = newObj;        // CS1656: 無法指派給 foreach 迴圈變數
    item.Property = 123;  // 允許:修改參考型別物件內容
    // 實值型別則完全不可修改 (複製品)
}
  • item 是唯讀區域變數
  • 不可作為 ref/out 參數傳遞
  • 參考型別:變數唯讀,但物件內容可修改

型別轉換規則


IEnumerable objs = new List { "a", "b" };
foreach (string s in objs) { } // 隱含轉換 object → string (執行期可能失敗)

// 明確轉換
foreach (string s in objs.Cast()) { }

集合元素型別需隱含轉換至迴圈變數型別,否則編譯錯誤。

陣列的特殊支援

  • 一維陣列:索引 0 到 Length-1 依序
  • 多維陣列:最右維度最先遞增 (Row-major)
    
    int[,] m = { {1,2}, {3,4}, {5,6} };
    foreach (var v in m) Console.Write(v + " "); // 1 2 3 4 5 6
    
  • 陣列 foreach 編譯器優化為索引存取,不建立列舉器物件,效能最佳

break / continue 行為


foreach (var item in collection)
{
    if (skipCondition) continue; // 跳過本項,進入下一項
    if (stopCondition) break;    // 完全離開迴圈
    Process(item);
}

行為與 while 迴圈一致。

效能比較

需求說明
公開 GetEnumerator()非靜態,回傳型別為類別/結構/介面
列舉器有 MoveNext()公開、非靜態、回傳 bool
列舉器有 Current 屬性公開、非靜態、可讀

常見陷阱

  • 修改集合內容:foreach 中 list.Add/Remove → InvalidOperationException (列舉器偵測版本變更)
  • 實值型別列舉器:List<T>.Enumerator 為 struct,foreach 複製列舉器,若手動 GetEnumerator() 忘記 using 可能導致邏輯錯誤
  • 捕捉迴圈變數:C# 5.0+ foreach 變數每次迴圈重新宣告,Lambda 捕捉正確;for 迴圈變數共享,需手動複製

總結

foreach 是 C# 遍歷集合的標準語法,語意清晰、支援鴨子類型、迴圈變數唯讀、陣列有編譯器優化。理解列舉器模式、唯讀語意、效能特性,能寫出正確且高效的迴圈程式碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
型別foreach 效能備註
陣列 (T[])★★★★★索引存取,無分配
List<T>★★★★☆結構體列舉器,無 boxing
自訂 IEnumerable<T>★★★☆☆介面調用、列舉器物件分配
非泛型 IEnumerable★★☆☆☆boxing、型別轉換開銷