C#的foreach 語句不會解析為IL 代碼中的foreach 語句。C#編譯器會把foreach 語句轉換為
IEnumerable 介面的方法和屬性。下面是一個簡單的foreach 語句,它迭代persons 數組中的所有元素,
並逐個顯示它們:
foreach (Person p in persons)
{
Console.WriteLine(p);
}
foreach 語句會解析為下面的程式碼片段。首先,調用GetEnumerator()方法,獲得數組的一個枚舉。
在while 迴圈中-- 只要MoveNext()返回true-- 用Current 屬性訪問數組中的元素:
IEnumerator enumerator = persons. GetEnumerator();
while (enumerator.MoveNext())
{
Person p = (Person) enumerator.Current;
Console.WriteLine(p);
}
C# 語言的 foreach 語句(在 Visual Basic 中為 for each)隱藏了枚舉數的複雜性。因此,建議使用foreach,而不直接操作枚舉數。
枚舉數可用於讀取集合中的資料,但不能用於修改基礎集合。
最初,枚舉數定位在集合中第一個元素前。Reset 方法還會將枚舉數返回到此位置。在此位置上,Current
屬性未定義。因此,在讀取 Current 的值之前,必須調用
MoveNext 方法將枚舉數提前到集合的第一個元素。
在調用 MoveNext 或 Reset 之前,Current 返回同一對象。MoveNext 將Current 設定為下一個元素。
如果 MoveNext 越過集合的末尾,則枚舉數將被放置在此集合中最後一個元素的後面,而且 MoveNext 返回false。當枚舉數位於此位置時,對
MoveNext 的後續調用也返回 false。如果上一個MoveNext 調用返回
false,則 Current 未定義。若要再次將Current 設定為集合的第一個元素,可以調用
Reset,然後再調用 MoveNext。
只要集合保持不變,枚舉數就保持有效。如果對集合變更(如添加、修改或刪除元素),則枚舉數將失效且不可恢複,而且其行為是不確定的。
枚舉數沒有對集合的獨佔訪問權;因此,枚舉通過集合在本質上不是一個安全執行緒的過程。若要確保枚舉過程中的安全執行緒,可以在整個枚舉過程中鎖定集合。若要允許多個線程訪問集合以進行讀寫操作,則必須實現自己的同步。