如果未来我们新增了其它的集合类,那么针对list的编码即使不做修改也能运行良好。在IMyEnumerable中声明的GetEnumerator方法返回一个继承了IMyEnuerator的对象。在MyList的内部,我们默认返回MyEnumerator。MyEnumerator就是迭代器的一个实现,如果对于迭代的需求有变化,我们可以重新开发一个迭代器,然后为MyList指定该迭代器就可以了。注意客户端的代码中,迭代的过程我们分别演示了for和while循环。因为使用了迭代器的缘故,两个循环都没有针对MyList编码,而是实现对迭代器的编码。
理解了我们自己实现的迭代器模式,就相当于理解了FCL中提供的对应模式。其实,上文代码中我们的接口名称中都加入了“My”字样,FCL中有相对应的这类接口,只不过我们为了演示的需要,增删了接口中的部分内容,但是大致的思路是一样的。
但是,问题也带来了。当集合类型因为某种需求,需要一个自定义迭代器的时候,FCL没有给我们公开这样的接口。所有的FCL集合,无论是泛型还是非泛型集合,都提供了GetEnumerator方法,没有提供SetEnumerator方法。注意到在我自己实现的集合类MyList 中,我公开了迭代器属性:
public IMyEnumerator MyEnumerator { get; set; } |
这样一来,可以让集合有新的迭代需求的时候,实现自己的迭代器。当然,如果没有为集合对象指定迭代器,那么它会返回一个默认迭代器,如下:
public IMyEnumerator GetEnumerator() { if (MyEnumerator == null) { return new MyEnumerator(this); } return MyEnumerator; } |
公开迭代器属性的好处就是,一旦迭代需求变化,我可以随时扩充我自己的迭代器,只要它继承IMyEnumerator接口。所以,为什么微软提供的FCL不让我们扩充迭代器呢?