概述

  • 迭代器(iterator)解决的是集合访问的问题,提供一种方法顺序访问一个聚合对象的各个元素,而不暴露该对象的内部表示。
  • 迭代器还有一个别名:游标(Cursor)。

应用

  • 访问一个具体对象的内容而不暴露它的内部表示;
  • 支持对聚合对象的多种遍历;
  • 为遍历不同的聚合结构提供一个统一的接口(即支持多态迭代)。

特点

  • 简化聚集的行为,迭代器具备了遍历的接口,这样聚集的接口就不必具备遍历接口;
  • 每一个聚集对象都可以有一个或者更多的迭代器对象,每一个迭代器的迭代状态可以彼此独立(外禀迭代器);
  • 遍历算法被封装到迭代器对象中,迭代算法可以独立于聚集对象变化。客户端不必知道聚集对象的类型,通过迭代器可以就读取和遍历聚集对象。这样的好处是聚集本身内部数据发生变化而不影响客户端的程序。

foreach语句与迭代器的关系

  • foreach循环语句可以用来迭代可枚举的集合中的所有元素。
  • 可枚举的:c#中,如果某个类型继承了接口IEnumerable,或者继承了泛型接口IEnumerable,或者继承了泛型接口IEnumerable的任何一个构造类型,那么就称这个类型是可枚举的。
  • foreach语句可以简化c#内置迭代器的使用复杂性。编译foreach语句,会生成调用GetEnumerator和MoveNext方法以及Current属性代码,这些方法和属性是内置迭代器所提供的。
  • foreach语句是微软提供的支持内置迭代器的语法糖,编译foreach语句后生成的代码与使用迭代器的代码完全一致。

实现迭代器方法

  • 对IEnumerable接口实现GetEnumerator方法,并自定义实现IEnumerator类或使用yield关键字。

foreach循环迭代可枚举类型流程

  1. 通过调用IEnumerator接口实现的IEnumerator的引用
  2. IEnumrator调用MoveNext方法
  3. MoveNext返回True时IEnumerator的Current属性获得对象引用,用于foreach循环
  4. 重复2 3步骤,直到MoveNext方法返回False

IEnumerable,IEnumerator概述

IEnumerable, IEnumerable, IEnumerator, IEnumberator,generic版本和non-generic版本稍有些不同。IEnumerable是那些可以被遍历的集合中所需要实现的基础接口,IEnumerable有一个方法GetEnumerator(),这个方法发回一个IEnumerator类型,IEnumerator包含一个Current属性和MoveNext和Reset方法,通过这些属性和方法就可以遍历这个集合了。对于IEnumerable和IEnumerator的实现,与non-generic版本稍有些不同,除了代码中的IEnumerable和IEnumerator换成对应的Generic接口后修改对应泛型占位符之外,还需要需要注意:IEnumerable需要实IEnumerable.GetEnumerator()方法;IEnumerator要实现Dispose()方法和IEnumerator.Current属性。

yield关键字

用IEnumerable, IEnumerable, IEnumerator, IEnumberator来实现一个可以遍历的类多少觉得有些麻烦,要多实现一个IEnumerator类。而且Generic版本要多实现几个方法和属性。yield关键字可以帮我们简化上述的过程,yield用于生成一个遍历类型,包含yield的方法的返回值类型必须是IEnumerable,IEnumerator,IEnumerable,IEnumerator其中一种。yield的一般形式是yield return < expression>。

总结

迭代器模式是设计模式中行为模式(behavioral pattern)的一个例子,他是一种简化对象间通讯的模式,也是一种非常容易理解和使用的模式。简单来说,迭代器模式使得你能够获取到序列中的所有元素而不用关心是其类型是array,list,linked list或者是其他什么序列结构。这一点使得能够非常高效的构建数据处理通道(data pipeline)即数据能够进入处理通道,进行一系列的变换,或者过滤,然后得到结果。事实上,这正是LINQ的核心模式。在.NET中,迭代器模式被IEnumerator和IEnumerable及其对应的泛型接口所封装。如果一个类实现了IEnumerable接口,那么就能够被迭代;调用GetEnumerator方法将返回IEnumerator接口的实现,它就是迭代器本身。迭代器类似数据库中的游标,他是数据序列中的一个位置记录。迭代器只能向前移动,同一数据序列中可以有多个迭代器同时对数据进行操作。总地来说,迭代器(Iterator)模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样即可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。迭代器模式在访问数组、集合、列表等数据时,尤其是数据库数据操作时,有非常普遍的应用,但由于它太普遍了,所以各种高级语言都对它进行了封装,所以反而给人感觉此模式本身不太常用了。

代码链接

参考:
https://segmentfault.com/a/1190000004846689
http://www.360doc.com/content/20/0817/17/71178898_930799249.shtml

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐