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]);
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:實際陣列長度
}
IEnumerator)// 陣列:直接產生 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。