一.為什麼數組和集合可以使用foreach遍歷
01. 因為數組和集合都實現了IEnumerable接口,該接口中只有一個方法,GetEnumerator()
02.數組類型是從抽象基類型 Array 派生的引用類型。由於此類型實現了 IEnumerable ,因此可以對 C# 中的所有數組使用 foreach 迭代。(摘自MSDN)
二.探討針對於List集合微軟的是怎麼實現這個IEnumerable接口的
該接口的方法
public interface IEnumerable { // 摘要: // 返回一個循環訪問集合的枚舉數。 // // 返回結果: // 一個可用於循環訪問集合的 System.Collections.IEnumerator 對象。 [DispId(-4)] IEnumerator GetEnumerator(); }
對於GetEnumerator這個方法他的返回值時又是一個接口類型。所以在這裡還要看IEnumerator的接口內容。
public interface IEnumerator { // 摘要: // 獲取集合中的當前元素。 // // 返回結果: // 集合中的當前元素。 object Current { get; } // 摘要: // 將枚舉數推進到集合的下一個元素。 // // 返回結果: // 如果枚舉數成功地推進到下一個元素,則為 true;如果枚舉數越過集合的結尾,則為 false。 // // 異常: // System.InvalidOperationException: // 在創建了枚舉數後集合被修改了。 bool MoveNext(); // // 摘要: // 將枚舉數設置為其初始位置,該位置位於集合中第一個元素之前。 // // 異常: // System.InvalidOperationException: // 在創建了枚舉數後集合被修改了。 void Reset(); }
所以不難發現微軟是通過這種方法的實現遍歷迭代變量的
三.通過C#代碼實現自定義類型的集合遍歷
首先該類必須實現IEnumerable接口
//01自定義類型:實現IEnumerable接口,證明這個類型保存的數據能被foreach遍歷 //IEnumberable這個接口,在微軟底層有一個方法GetEnumerator()返回值類型是IEnumerator接口 public class MyList:IEnumerable { //02定義一個集合 ArrayList list=new ArrayList(); //03實現IEnumberable的方法 public IEnumerator GetEnumerator() { return new MyIEnumerator(list); } public void Add(Object oj) { list.Add(oj); } }
//IEnumerator:支持對非泛型集合的簡單迭代 public class MyIEnumerator:IEnumerator { //01定義一個List集合 ArrayList list=new ArrayList(); //02無參構造 public MyIEnumerator(ArrayList list) { //跟當前類的集合賦值 this.list = list; } public object Current { get { return list[index]; } } //04默認將集合的索引指向前一個 private int index = -1; //05實現接口的Movenext方法 public bool MoveNext() { bool happy = false;//默認為沒有數據 if (list.Count - 1 > index) { //證明集合中有數據讓索引加1 index++; //改變bool值為true happy = true; } return happy; } public void Reset() { index = -1; } }
MyList list=new MyList(); list.Add("小王"); list.Add("小李"); foreach (string item in list) { Console.WriteLine(item); } Console.ReadKey();