- 之前一直不是很清楚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(); } } }