foreach遍历本质论
foreach遍历本质:
我们都知道能用foreach遍历的对象都要实现IEnumerable(或其对应的泛型接口)这个接口,可你知道为什么吗?
这就要看foreach遍历对象的时候到底做了什么?
简要概述,foreach遍历的时候做了两件事:
第一件,就是隐式调用GetEnumerator()这个方法。这个方法是什么东东,那就是IEnumerable这个接口有且仅有的一个成员, public IEnumerator GetEnumerator();
所以想要用foreach遍历的对象必须实现IEnumerable这个接口,本质是实现这个方法,只要你的类中有这个方法,不实现这个接口也无所谓了;
第二件,请别急,要想知道第二件事做了什么,请先看看第一件事中public IEnumerator GetEnumerator();这个方法返回的东西,IEnumerator类型的对象,
那IEnumerator接口又有哪些东东,如下,1个属性2个方法:object Current { get; } //返回当前对象 bool MoveNext();//将枚举数推进到集合的下一个元素。 如果枚举数成功地推进到下一个元素,则为 true;如果枚举数越过集合的结尾,则为 false。 void Reset(); // 将枚举数设置为其初始位置,该位置位于集合中第一个元素之前。
好了,现在可以告诉你foreach第二件事到底做了什么,就是调用返回的IEnumerator对象(枚举器)的MoveNext()方法 ,如果该方法返回true,就将Current属性赋值给迭代变量,
如果返回的是false,就跳出foreach语句块。
三种实现枚举器的方式:
继承:IEnumerable|IEnumerator
继承:IEnumerable<T>|IEnumerator<T>
不继承接口,但遍历的对象具有GetEnumerator()这个方法,且该方法返回的对象实现了Current属性和MoveNext()、Reset()方法。
附加:一般而言,枚举器不易实现,但是通过使用迭代器可以显著简化该任务。详见我的下篇博客。

浙公网安备 33010602011771号