C#接口之IEnumerable,IEnumerator

IEnumerable

                           

截图来源于https://msdn.microsoft.com/zh-cn/library/system.collections.ienumerable.getenumerator.aspx

IEnumerable只包含一个抽象方法GetEnumerable(),它返回一个可用于循环访问集合的IEnumberator对象。我们可以通过定义foreach语句功能实现并支持非泛型方法的迭代。

在MSDN上给出了一个关于GetEnumerable()方法的例子:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Collections;
  7 
  8 namespace TestInterface
  9 {
 10 
 11     public class Person
 12     {
 13         public Person(string fName,string lName)
 14         {
 15             this.firstName = fName;
 16             this.lastName = lName;
 17         }
 18 
 19         public string firstName;
 20         public string lastName;
 21     }
 22 
 23     public class People:IEnumerable//继承IEnumerable类,重写GetNumberable()方法
 24     {
 25         private Person[] _peopele;
 26         public People(Person[] pArray)
 27         {
 28             _peopele = new Person[pArray.Length];
 29             for (int i = 0; i < pArray.Length; i++)
 30                 _peopele[i] = pArray[i];
 31         }
 32 
 33         IEnumerator IEnumerable.GetEnumerator()//实现GetEnumerable接口
 34         {
 35             return (IEnumerator) GetEnumerator();//调用重写的GetEnumerator方法
 36         }
 37 
 38         public PeopleEnum GetEnumerator()
 39         {
 40             return new PeopleEnum(_peopele);//返回一个PeopleEnum类型的对象,PeopleEnum继承了IEnumerator类
 41         }
 42     }
 43 
 44     public class PeopleEnum:IEnumerator
 45     {
 46         public Person[] _people;
 47         int position = -1;
 48         /// <summary>
 49         /// 构造函数
 50         /// </summary>
 51         /// <param name="list">
 52         /// _people指针指向list数组
 53         /// </param>
 54         public PeopleEnum(Person[] list)
 55         {
 56             _people = list;
 57         }
 58 
 59         /// <summary>
 60         ///将枚举数推进到集合的下一个元素。 61         /// </summary>
 62         /// <returns>
 63         /// 成功返回true,失败返回false
 64         /// </returns>
 65         public bool MoveNext()
 66         {
 67             position++;
 68             return (position < _people.Length);
 69         }
 70 
 71         /// <summary>
 72         /// 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
 73         /// </summary>
 74         public void Reset()
 75         {
 76             position = -1;
 77         }
 78 
 79         /// <summary>
 80         /// 获取当前位置的对象
 81         /// </summary>
 82         object IEnumerator.Current
 83         {
 84             get { return Current; }
 85         }
 86 
 87         /// <summary>
 88         /// 实现接口方法
 89         /// </summary>
 90         public Person Current
 91         {
 92             get 
 93             {
 94                 try 
 95                 {
 96                     return _people[position];
 97                 }
 98                 catch(IndexOutOfRangeException)
 99                 {
100                     throw new InvalidOperationException();
101                 }
102             }
103         }
104     }
105 
106     class Program
107     {
108        
109         static void Main(string[] args)
110         {
111             Person[] peopleArray = new Person[3]
112             {
113                 new Person("John","Smith"),
114                 new Person("Jim","Johnson"),
115                 new Person("Sue","Rabon"),
116             };
117             People peopleList = new People(peopleArray);//初始化对象集合
118             foreach (Person p in peopleList)
119                 Console.WriteLine(p.firstName + " " + p.lastName);
120           
121         }
122     }
123 }

如果我们将第23-42代码改写如下:

 1  public class People//继承IEnumerable类,重写GetNumberable()方法
 2     {
 3         private Person[] _peopele;
 4         public People(Person[] pArray)
 5         {
 6             _peopele = new Person[pArray.Length];
 7             for (int i = 0; i < pArray.Length; i++)
 8                 _peopele[i] = pArray[i];
 9         }
10     }

即不让People继承IEnumerable类,重写GetNumerator接口的部分也删除掉。那么编译器就会提示:

这是因为People类中没有实现GetNumerator()方法,所以People对象就不能返回一个IEnumerator对象,以至于foreach语句不能遍历Person集合。

IEnumerator

下面来介绍一下IEnumerator

截图来源于:https://msdn.microsoft.com/zh-cn/library/system.collections.ienumerator(v=vs.110).aspx

属性                        描述


Current                获取集合中的当前元素


方法                       描述


MoveNext             将枚举数推进到集合的下一个元素。


Reset                   将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。


正是因为People类中没有实现GetNumerator()方法,所以People对象就不能返回一个IEnumerator对象,那么也就不能使用MoveNext方法,foreach也就不能实现遍历Person集合。

原文地址:https://www.cnblogs.com/tgycoder/p/4891966.html