c#中的IEnumerable和IEnumerator

  • 之前一直不是很清楚IEnumerable和IEnumerator 具体区别 今天特地为此编写了一个自己 枚举类 继承自IEnumerable和IEnumerator 接口,我发现如果只继承IEnumerable而不继承IEnumerator 接口 是不可以实现foreach循环访问的因为使用foreach循环必须实现GetEumerator函数.IEnumerable是声明该类可以使用foreach循环访问,而IEnumerator是枚举器具体实现,也就是说 如果类继承了IEnumerable接口则表明此类对象是可以枚举的,具体怎么枚举则需要继承并实现IEnumerator接口.

public IEnumerator GetEnumerator()
{

return (IEnumerator)this;

}

另外我还发现,IEnumerator 接口的2个函数和一个属性 中 MoveNext()是自动调用执行的,Current是自动访问的,而且顺序是 使用foreach循环时首先执行MoveNext()函数把索引往后移一位,然后访问Current当前属性的值.所以当你继承这2个接口时索引定义要从 -1开始这样第一个访问的才能是数组索引为零的元素.

以下是我的实验代码和结果:


using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Collections;
 namespace test
 {
 struct point
 {
 public int x;
 public int y;
 public int z;
 }

class Myenum : IEnumerable, IEnumerator
 {
 private int index;
 private point[] points;

public Myenum(int numofpoint)
 {
 this.index = -1;
 points = new point[numofpoint];

for (int i = 0; i < points.Length; i++)
 {
 points[i].x = i;
 points[i].y = i * i;
 points[i].z = i * i * i;
 }
 }
 public IEnumerator GetEnumerator()
 {

return (IEnumerator)this;

}
 public object Current
 {
 get
 {
 Console.WriteLine("Current");
 return points[index];
 }
 }
 public bool MoveNext()
 {

index++;

if (index < points.Length&&index>=0)
 {
 Console.WriteLine("MoveNext()");
 return true;
 }
 else
 return false;

}
 public void Reset()
 {
 index = -1;
 Console.WriteLine("Reset()");
 }

}
 class Program
 {
 static void Main(string[] args)
 {

Myenum enum1 = new Myenum(5);

foreach (point p in enum1)
 {
 Console.WriteLine("(" + p.x.ToString() + "," + p.y.ToString() + "," + p.z.ToString() + ")");
 }

Console.Read();

}
 }
 }