实现自定义集合的可枚举类型(IEnumerable)和枚举数(IEnumerator )

下面的代码示例演示如何实现自定义集合的 IEnumerable 和 IEnumerator 接口:

  1 using System;
  2 using System.Collections;
  3 using System.Collections.Generic;
  4 using System.Linq;
  5 using System.Text;
  6 using System.Threading.Tasks;
  7 
  8 namespace ConsoleApplication1
  9 {
 10     public class Person
 11     {
 12         public Person(string fName, string lName)
 13         {
 14             this.firstName = fName;
 15             this.lastName = lName;
 16         }
 17 
 18         public string firstName;
 19         public string lastName;
 20     }
 21 
 22     public class People : IEnumerable
 23     {
 24         private Person[] _people;
 25         public People(Person[] pArray)
 26         {
 27             _people = new Person[pArray.Length];
 28 
 29             for (int i = 0; i < pArray.Length; i++)
 30             {
 31                 _people[i] = pArray[i];
 32             }
 33         }
 34 
 35         IEnumerator IEnumerable.GetEnumerator()
 36         {
 37             return (IEnumerator)GetEnumerator();
 38         }
 39 
 40         public PeopleEnum GetEnumerator()
 41         {
 42             return new PeopleEnum(_people);
 43         }
 44     }
 45 
 46     public class PeopleEnum : IEnumerator
 47     {
 48         public Person[] _people;
 49 
 50         // Enumerators are positioned before the first element
 51         // until the first MoveNext() call.
 52         int position = -1;
 53 
 54         public PeopleEnum(Person[] list)
 55         {
 56             _people = list;
 57         }
 58 
 59         public bool MoveNext()
 60         {
 61             position++;
 62             return (position < _people.Length);
 63         }
 64 
 65         public void Reset()
 66         {
 67             position = -1;
 68         }
 69 
 70         object IEnumerator.Current
 71         {
 72             get
 73             {
 74                 return Current;
 75             }
 76         }
 77 
 78         public Person Current
 79         {
 80             get
 81             {
 82                 try
 83                 {
 84                     return _people[position];
 85                 }
 86                 catch (IndexOutOfRangeException)
 87                 {
 88                     throw new InvalidOperationException();
 89                 }
 90             }
 91         }
 92     }
 93 
 94 
 95     class Program
 96     {
 97         static void Main(string[] args)
 98         {
 99             Person[] peopleArray = new Person[3]
100             {
101                 new Person("John", "Smith"),
102                 new Person("Jim", "Johnson"),
103                 new Person("Sue", "Rabon"),
104             };
105 
106             People peopleList = new People(peopleArray);
107             foreach (Person p in peopleList)
108                 Console.WriteLine(p.firstName + " " + p.lastName);
109         }
110     }
111 }

可枚举类型 → 实现IEnumerable接口,可以不需要直接实现这个接口,但必须有个GetEnumerator方法,返回值类型必须为IEnumerator类型,也就是第四点最后一段代码中接口注释的那种写法!

枚举数 → 实现IEnumerator接口,实现全部方法,首先是调用GetEnumerator返回一个类型为IEnumerator的枚举数,然后编译器会隐式的调用实现IEnumerator类中的方法和属性!

总结:所以实现foreach遍历,必须达到上面的两种条件才能进行遍历对象,他们可以写在一起也可以分开,最好是分开,进行职责分离,一个类干一件事总归是好事!也满足面向对象的单一指责设计原则。

原文地址:https://www.cnblogs.com/jshchg/p/11572039.html