IEnumerable, IEnumerator接口
2017-06-04 17:06 Dirichlet 阅读(184) 评论(0) 编辑 收藏 举报IEnumerable接口
// Exposes the enumerator, which supports a simple iteration over a non-generic collection.
public interface IEnumerable {// Returns an enumerator that iterates through a collection. IEnumerator GetEnumerator(); }
IEnumerator接口
// Supports a simple iteration over a nongeneric collection.
public interface IEnumerator {// Gets the current element in the collection. object Current { get; } // Advances the enumerator to the next element of the collection. bool MoveNext(); // Sets the enumerator to its initial position, which is before the first element in the collection. void Reset(); }
示例1:
class MyClass : IEnumerable { private int[] sources; public MyClass() { this.sources = new int[] { 0, 1, 3, 3, 4, 5, 5, 7, 8, 1, 3, 4, 9, 9, 9, 9, 90, 0, 0 }; } public int this[int index] { get { return this.sources[index]; } } public int Length { get { return this.sources.Length; } } public IEnumerator GetEnumerator() { return new MyClassEnumerator(this); } } class MyClassEnumerator : IEnumerator { private MyClass myobject; private int index = -1; public MyClassEnumerator(MyClass myobject) { this.myobject = myobject; } public object Current { get { return this.myobject[index]; } } public bool MoveNext() { if (this.index < this.myobject.Length - 1) { this.index++; return true; } return false; } public void Reset() { this.index = -1; } } static void Main(string[] args) { MyClass myobject = new MyClass(); foreach (var item in myobject) { Console.WriteLine(item); } return; }
示例2: 用yield关键字简化实现.
yield是一个语法糖, 编译器会重新翻译这段代码, 实际上是返回了一个实现了IEnumerator 的对象, 每一次的yield循环对应MoveNext, return this[i]对应于Current属性.
参考:http://www.cnblogs.com/artech/archive/2013/04/14/yield-in-wcf-02.html
class MyClass : IEnumerable { private int[] sources; public MyClass() { this.sources = new int[] { 0, 1, 3, 3, 4, 5, 5, 7, 8, 1, 3, 4, 9, 9, 9, 9, 90, 0, 0 }; } public int this[int index] { get { return this.sources[index]; } } public int Length { get { return this.sources.Length; } } public IEnumerator GetEnumerator() { //return new MyClassEnumerator(this); for (int i = 0; i < this.Length; i++) { yield return this[i]; } } }
示例3: 一个对象同时实现了IEnumerable, IEnumerator. 这个实例仅供实验研究, 不推荐实际中应用.
提问: 为什么还要实现IEnumerable, 直接实现了IEnumerator就可以foreach不行吗?
回答: 请把枚举器想象成类似指针的功能, 可以遍历指向的集合.但是一个集合对象最好允许有多个枚举器, 如果集合对象直接实现IEnumerator, 集合对象和枚举器就耦合在一起,一个集合对象就只能有一个枚举器了,也就是它本身就是自己的枚举器。就算是不考虑支持多种枚举器,只考虑对一个枚举器的同时进行多次枚举,只实现IEnumerable也是做不到。
1 class MyClass : IEnumerable, IEnumerator 2 { 3 private int[] sources; 4 private int index = -1; 5 6 public MyClass() 7 { 8 this.sources = new int[] { 0, 1, 3, 3, 4, 5, 5, 7, 8, 1, 3, 4, 9, 9, 9, 9, 90, 0, 0 }; 9 } 10 11 public int this[int index] 12 { 13 get { return this.sources[index]; } 14 } 15 16 public int Length { get { return this.sources.Length; } } 17 18 public IEnumerator GetEnumerator() 19 { 20 //return new MyClassEnumerator(this); 21 for (int i = 0; i < this.Length; i++) 22 { 23 yield return this[i]; 24 } 25 } 26 27 public object Current 28 { 29 get { return this[index]; } 30 } 31 32 public bool MoveNext() 33 { 34 if (this.index < this.Length - 1) 35 { 36 this.index++; 37 return true; 38 } 39 40 return false; 41 } 42 43 public void Reset() { this.index = -1; } 44 } 45 46 static void Main(string[] args) 47 { 48 MyClass myobject = new MyClass(); 49 50 foreach (var item in myobject) 51 { 52 Console.WriteLine(item); 53 } 54 55 }
参考:
http://www.cnblogs.com/artech/archive/2013/04/14/yield-in-wcf-02.html