【实现foreach遍历】
IEnumerable的原始版本存在于System.Collection中。
一个类想要被foreach遍历,需要实现此IEnumerable接口。
1 public class People : IEnumerable 2 { 3 private Person[] _people; 4 public People(Person[] pArray) 5 { 6 _people = new Person[pArray.Length]; 7 8 for (int i = 0; i < pArray.Length; i++) 9 { 10 _people[i] = pArray[i]; 11 } 12 } 13 14 IEnumerator IEnumerable.GetEnumerator() 15 { 16 return (IEnumerator) GetEnumerator(); 17 } 18 19 public PeopleEnum GetEnumerator() 20 { 21 return new PeopleEnum(_people); 22 } 23 } 24 25 class App 26 { 27 static void Main() 28 { 29 Person[] peopleArray = new Person[3] 30 { 31 new Person("John", "Smith"), 32 new Person("Jim", "Johnson"), 33 new Person("Sue", "Rabon"), 34 }; 35 36 People peopleList = new People(peopleArray); 37 foreach (Person p in peopleList) 38 Console.WriteLine(p.firstName + " " + p.lastName); 39 40 } 41 }
为了遍历能真正成功,需要返回一个实现了IEnumerator的迭代器。
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(); } } } }
IEnumerator原型如下:
【泛型版本】
IEnumerator默认返回的是object,为了适应多种不同的情形,微软为IEnumerator提供了一个泛型版本。
上面看到,IEnumerator是由IEnumerable返回,显然IEnumerable必须提供这个T。所以IEnuemrable也有相应的泛型版本。
参考:http://msdn.microsoft.com/zh-cn/library/9eekhta0(v=vs.110).aspx