一直对IEnumerable和IEnumerator的感觉到非常迷惑,后来我突然从接口定义的角度来思考
这两个东西,感觉迷惑减少很多,于是按照接口来分析一下。
1,什么是接口?
接口就是你定义一些方法或者属性,但是不实现,让继承你的类去实现。凡是继承接口的类必须实现接口。比如这两个接口的定义如下:
public interface IEnumerable //(接口)枚举数定义 { IEnumerator GetEnumerator();//只有一个方法,返回类型是IEnumerator } public interface IEnumerator//(接口)枚举器定义 { Object Current { get; } //属性,返回类型Object bool MoveNext(); //读Current值之前,MoveNext将枚举数提前到集合的第一个元素。 void Reset();//将枚举数被定位于集合中第一个元素的前面 }
2,分析接口
如果你想使用枚举,就必须实现接口IEnumerable的方法GetEnumerator(),但是这个方法
返回类型是IEnumerator,他才是真正的实现枚举的功臣,因此要枚举的容器就必须实现
IEnumerator的方法和属性。
这里面我们可以使用让容器a实现IEnumerable,这个容器a也是我们想要枚举的容器。
使用容器b实现IEnumerator,当然容器a和b装的数据是相同的。
容器a直接使用GetEnumerator()得到IEnumerator对象(容器b).
3,下面通过例子来看一下,这个例子取自msdn,但是直接看例子不好懂,我将必要的东西提出来,如下:
(1)People相当于容器a,PeopleEnum相当于容器b。
public class Person //一个人 { } public class People : IEnumerable //人的容器,需要实现 IEnumerable接口的成员 { IEnumerator IEnumerable.GetEnumerator() //实现接口IEnumerable的唯一成员 { return (IEnumerator)GetEnumerator(); //返回类型转为IEnumerator } public PeopleEnum GetEnumerator() //自定义方法 { return new PeopleEnum(_people); } } public class PeopleEnum : IEnumerator //IEnumerator的子类 { public PeopleEnum(Person[] list) //构造函数 { } public bool MoveNext() //IEnumerator的方法 { } public void Reset() //IEnumerator的方法 { } object IEnumerator.Current //IEnumerator的属性 { get { return Current; } } public Person Current { } }
People 实现 IEnumerable 说明People是可以枚举的,但是怎么枚举呢?
PeopleEnum 实现 IEnumerator ,真正的实现了枚举。他们通过GetEnumerator建立联系。
(2)下面是这个完整的例子:

using System; using System.Collections; public class Person { public Person(string fName, string lName) { this.firstName = fName; this.lastName = lName; } public string firstName; public string lastName; } public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } IEnumerator IEnumerable.GetEnumerator() { return (IEnumerator) GetEnumerator(); } public PeopleEnum GetEnumerator() { return new PeopleEnum(_people); } } public class PeopleEnum : IEnumerator { public Person[] _people; // Enumerators are positioned before the first element // until the first MoveNext() call. int position = -1; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position++; return (position < _people.Length); } public void Reset() { position = -1; } object IEnumerator.Current { get { return Current; } } public Person Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } } class App { static void Main() { Person[] peopleArray = new Person[3] { new Person("John", "Smith"), new Person("Jim", "Johnson"), new Person("Sue", "Rabon"), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) Console.WriteLine(p.firstName + " " + p.lastName); } }
3,下面再给一个连接,也是解释这个的
http://www.cnblogs.com/illele/archive/2008/04/21/1164696.html