一 : IEnumerable
公开枚举数,该枚举数支持在非泛型集合上进行简单迭代。
IEnumerable是可以枚举的所有非泛型集合的基接口,IEnumerable包含单个方法GetEnumerator,它将返回IEnumerator。 IEnumerator提供了通过公开循环访问集合的能力Current属性和MoveNext和Reset方法。【官方解释】
1 public class Computer : IEnumerator 2 { 3 List<T> list = null; 4 public Computer() 5 { 6 list = new List<T>(); 7 } 8 9 public void Add(string str) 10 { 11 list.Add(str); 12 } 13 14 public IEnumerator GetEnumerator() 15 { 16 for (int i = 0; i < list.Count; i++) 17 { 18 yield return list[i]; 19 } 20 } 21 }
官方示例:实现IEnumerable和IEnumerator为自定义集合的接口(foreach的内部实现)
1 public class Person 2 { 3 public Person(string fName, string lName) 4 { 5 this.firstName = fName; 6 this.lastName = lName; 7 } 8 9 public string firstName; 10 public string lastName; 11 } 12 13 public class People : IEnumerable 14 { 15 private Person[] _people; 16 public People(Person[] pArray) 17 { 18 _people = new Person[pArray.Length]; 19 20 for (int i = 0; i < pArray.Length; i++) 21 { 22 _people[i] = pArray[i]; 23 } 24 } 25 26 IEnumerator IEnumerable.GetEnumerator() 27 { 28 return (IEnumerator)GetEnumerator(); 29 } 30 31 public PeopleEnum GetEnumerator() 32 { 33 return new PeopleEnum(_people); 34 } 35 } 36 37 public class PeopleEnum : IEnumerator 38 { 39 public Person[] _people; 40 41 int position = -1; 42 43 public PeopleEnum(Person[] list) 44 { 45 _people = list; 46 } 47 48 public bool MoveNext() 49 { 50 position++; 51 return (position < _people.Length); 52 } 53 54 public void Reset() 55 { 56 position = -1; 57 } 58 59 object IEnumerator.Current 60 { 61 get 62 { 63 return Current; 64 } 65 } 66 67 public Person Current 68 { 69 get 70 { 71 try 72 { 73 return _people[position]; 74 } 75 catch (IndexOutOfRangeException) 76 { 77 throw new InvalidOperationException(); 78 } 79 } 80 } 81 } 82 class Program 83 { 84 static void Main(string[] args) 85 { 86 Person[] peopleArray = new Person[3] 87 { 88 new Person("John", "Smith"), 89 new Person("Jim", "Johnson"), 90 new Person("Sue", "Rabon"), 91 }; 92 93 People peopleList = new People(peopleArray); 94 95 foreach (Person p in peopleList) 96 Console.WriteLine(p.firstName + " " + p.lastName); 97 } 98 }
二:IEnumerator
支持对非泛型集合的简单迭代。
C# 语言的 foreach 语句隐藏了枚举数的复杂性。 因此,建议使用foreach而不是直接操作枚举数。