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

Effective C# 原則 11:優先使用 foreach 迴圈(上)

     編輯:關於C語言

三種迴圈寫法比較

int[] foo = new int[100];

// 1. foreach(推薦)
foreach (int i in foo) Console.WriteLine(i);

// 2. for + Length 屬性存取
for (int i = 0; i < foo.Length; i++) Console.WriteLine(foo[i]);

// 3. for + 快取 Length(C/C++ 風格,❌ 最差)
int len = foo.Length;
for (int i = 0; i < len; i++) Console.WriteLine(foo[i]);

為何寫法 3 最差?

CLR 安全機制:每次陣列存取皆做邊界檢查。JIT 嘗試將檢查移出迴圈(Hoisting),但寫法 3 將 len 抽離導致 JIT 無法證明 i < foo.Length 恆真,反而產生雙重邊界檢查:

// 實際產生的邏輯
for (int i = 0; i < len; i++)
{
    if (i < foo.Length) // 檢查 1:len 版本
        Console.WriteLine(foo[i]);
    else
        throw new IndexOutOfRangeException(); // 檢查 2:實際陣列長度
}

foreach / 寫法 2 為何較快

  • JIT 識別標準模式,將邊界檢查提升至迴圈外
  • 單次檢查保證全迴圈安全
  • C# 1.0 曾因裝箱導致 foreach 較慢,現代版本已最佳化(陣列不經 IEnumerator)

foreach 編譯器展開

// 陣列:直接產生 for 迴圈,無裝箱
for (int i = 0; i < foo.Length; i++)
    Console.WriteLine(foo[i]);

// 集合:使用 IEnumerator
var enumerator = collection.GetEnumerator();
while (enumerator.MoveNext())
{
    var item = (T)enumerator.Current; // 參考型別無裝箱,值型別有裝箱
    Console.WriteLine(item);
}

核心建議

預設使用 foreach。它語意清晰、自動最佳化、免手動管理索引與邊界。只有需要索引、反向、跳躍遍歷時才用 for。

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