在foreach語句中使用枚舉,可以疊代數組或集合中的元素,且無須知道集合中的元素的個數。如圖顯示了調用foreach方法的用戶端和集合之間的關系。數組或集合實作帶GetEnumerator()方法的IEnumerable接口。GetEnumerator()方法傳回一個實作lEnumerable接口的枚舉,接着foreach語句就可以使用IEnumerable接口疊代集合了。
GetEnumerator()方法用IEnumerable接口定義,foreach語句并不真的需要在集合類中實作這個接口。有一個名為GetEnumerator()的方法它傳回實作了IEnumerator接口的對象就足夠了。

先定義一個Person類,這個類有自動實作的屬性Firstname和Lastname,以及從Object類重寫ToString方法和繼承泛型接口IEquatable以比較兩個對象是否相等,實作泛型接口IComparer以比較兩個對象用來排序。
建立一個三個元素的person數組,現對數組進行排序在用foreach循環通路數組中的元素并輸出
分析foreach (var person in persons)Console.WriteLine(person);這段代碼IL代碼
C#的foreach語句不會解析為IL代碼中的foreach語句,C#編譯器會把foreach語句轉換為IEnumerable接口的方法和屬性,foreach語句使用IEnumerator接口的方法和屬性,疊代數組中的所有元素,為此,IEnumerator定義了Current屬性,來傳回光标所在的元素,該接口的MoveNext()方法移動到數組的下一個元素上,如果有這個元素該方法就傳回true否則傳回false,這個接口的泛型版本IEnumerator派生自接口IDisposable,是以定義了Dispose()方法來清理枚舉器占用的資源,使用foreach語句會解析為下面的代碼段
為了友善的建立枚舉器,C#添加了yield語句,yield return 語句傳回集合的一個元素,并移動到下一個元素,yield break 可停止疊代。使用疊代塊,編譯器會生成一個yield類型,其中包含一個狀态機,如下代碼段所示。yield 類型實作IEnumerator和IDisposable接口的屬性和方法。在下面的例子中,可以把yield類型看作内部類Enumerator.外部類的GetEnumerator()方法執行個體化并傳回一個新的yield類型。在yield類型中,變量state定義了疊代的目前位置,每次調用MoveNext()時,目前位置都會改變,MoveNext()封裝了疊代代碼,并設定了current變量的值,進而使Current屬性根據位置傳回一個對象。
本文轉自xmgdc51CTO部落格,原文連結:http://blog.51cto.com/12953214/1944068 ,如需轉載請自行聯系原作者