一.为什么数组和集合可以使用foreach遍历
01. 因为数组和集合都实现了IEnumerable接口,该接口中只有一个方法,GetEnumerator()
02.数组类型是从抽象基类型 Array 派生的引用类型。由于此类型实现了 IEnumerable ,因此可以对 C# 中的所有数组使用 foreach 迭代。(摘自MSDN)
二.探讨针对于List集合微软的是怎么实现这个IEnumerable接口的
该接口的方法
public interface IEnumerable { // 摘要: // 返回一个循环访问集合的枚举数。 // // 返回结果: // 一个可用于循环访问集合的 System.Collections.IEnumerator 对象。 [DispId(-)] 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默认将集合的索引指向前一个 ; //05实现接口的Movenext方法 public bool MoveNext() { bool happy = false;//默认为没有数据 > index) { //证明集合中有数据让索引加1 index++; //改变bool值为true happy = true; } return happy; } public void Reset() { index = -; } }
MyList list=new MyList(); list.Add("小王"); list.Add("小李"); foreach (string item in list) { Console.WriteLine(item); } Console.ReadKey();