C# foreach 可迭代任何實作 IEnumerable/IEnumerable<T> 的型別,陣列隱含實作。
| 語言 | 集合迭代 | 陣列迭代 |
|---|---|---|
| Java/C++ | | |
| C# | foreach (var item in collection) { ... } | foreach (var item in array) { ... } |
// 編譯器轉換為 (簡化版)
IEnumerator enumerator = collection.GetEnumerator();
try {
while (enumerator.MoveNext()) {
T item = enumerator.Current;
// loop body
}
}
finally {
(enumerator as IDisposable)?.Dispose();
}
public class Fibonacci : IEnumerable {
public IEnumerator GetEnumerator() => new FibonacciEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
private class FibonacciEnumerator : IEnumerator {
int _prev = 0, _curr = 1;
public int Current => _prev;
object IEnumerator.Current => Current;
public bool MoveNext() {
(_prev, _curr) = (_curr, _prev + _curr);
return true; // 無限序列
}
public void Reset() => (_prev, _curr) = (0, 1);
public void Dispose() { }
}
}
// 使用
foreach (int n in new Fibonacci().Take(10)) Console.WriteLine(n);
| 特性 | 類別 (參考型別) | 結構 (值型別) |
|---|---|---|
| 記憶體配置 | 堆積 | 堆疊 / 內嵌於包含型別 |
| 指派語意 | 參考複製 | 值複製 |
| 預設值 | null | 零值 (所有欄位為 0/null) |
| 繼承 | 支援繼承 | 不可繼承 (隱含 sealed) |
| 介面實作 | 支援 | 支援 |
| 解構子 | 有 (Finalize) | 無 |
| null 可用性 | 可為 null | 不可為 null (除非 Nullable<T>) |
public struct Vector3 {
public float X, Y, Z;
public Vector3(float x, float y, float z) => (X, Y, Z) = (x, y, z);
public float Magnitude => MathF.Sqrt(X*X + Y*Y + Z*Z);
public static Vector3 operator +(Vector3 a, Vector3 b)
=> new Vector3(a.X+b.X, a.Y+b.Y, a.Z+b.Z);
}
// 使用
Vector3 v1 = new Vector3(1, 2, 3);
Vector3 v2 = v1; // 值複製
v2.X = 10; // v1 不受影響
Vector3[] vectors = new Vector3[1000]; // 連續記憶體區塊,單一配置
Vector3[1000] 為單一記憶體區塊,無 1000 個獨立物件標頭
int i = 5;
Console.WriteLine(i.ToString()); // int 為 System.Int32 結構別名
long l = 10L; // System.Int64
double d = 3.14; // System.Double
// 所有基本型別皆為結構別名
int i = 42;
object boxed = i; // 裝箱:配置物件包裝值
int unboxed = (int)boxed; // 拆箱:提取值
// 概念模型
class Int32Box { public int Value; Int32Box(int v) => Value = v; }
object boxed2 = new Int32Box(42); // 裝箱相當於
int unboxed2 = ((Int32Box)boxed2).Value; // 拆箱相當於
List<int> 而非 ArrayListIComparable<T> 而非 IComparableobject 參數foreach 統一了集合與陣列的迭代語法,結構提供高效能值型別語意。理解值/參考語意差異、裝箱拆箱機制、避免不必要配置,是寫出高效能 C# 程式碼的關鍵。