【迭代器模式在.NET中的应用】

迭代器模式

  定义参考 wiki: Iterator pattern

  迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。   ------- 节选自 《大话设计模式》P207

  我们可以将迭代器模式抽离出几个重要组成部分:

  1. 迭代器抽象类

  2. 聚集抽象类

  3. 具体迭代器类

  4. 具体聚集类

1. 迭代器抽象类

 1 public interface IEnumerator
 2 {
 3         bool MoveNext();
 4
 5         Object Current {
 6             get;
 7         }
 8
 9         void Reset();
10 }

reference: .NET IEnumerator

2. 聚集抽象类

1 public interface IEnumerable
2 {
3         IEnumerator GetEnumerator();
4 }

reference: .NET IEnumerable

3. 具体迭代器类

通过查看.NET代码可以知道,在List、Dictionary类中都声明了具体的迭代器struct Enumerator,List中Enumerator代码如下:

 1 [Serializable]
 2 public struct Enumerator : IEnumerator<T>,
 3 System.Collections.IEnumerator
 4 {
 5             private List<T> list;
 6             private int index;
 7             private int version;
 8             private T current;
 9
10             internal Enumerator(List<T> list) {
11                 this.list = list;
12                 index = 0;
13                 version = list._version;
14                 current = default(T);
15             }
16
17             public void Dispose() {
18             }
19
20             public bool MoveNext() {
21
22                 List<T> localList = list;
23
24                 if (version == localList._version && ((uint)index < (uint)localList._size))
25                 {
26                     current = localList._items[index];
27                     index++;
28                     return true;
29                 }
30                 return MoveNextRare();
31             }
32
33             private bool MoveNextRare()
34             {
35                 if (version != list._version) {
36                     ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
37                 }
38
39                 index = list._size + 1;
40                 current = default(T);
41                 return false;
42             }
43
44             public T Current {
45                 get {
46                     return current;
47                 }
48             }
49
50             Object System.Collections.IEnumerator.Current {
51                 get {
52                     if( index == 0 || index == list._size + 1) {
53                          ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen);
54                     }
55                     return Current;
56                 }
57             }
58
59             void System.Collections.IEnumerator.Reset() {
60                 if (version != list._version) {
61                     ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion);
62                 }
63
64                 index = 0;
65                 current = default(T);
66             }
67 }

reference: .NET List Enumerator

4. 具体聚集类

同样以List为例,reference: .NET List

5. 利用 foreach 来遍历对象

foreach(int i in obj) {...}经过编译器转换将会变成如下:

var tmp = obj.GetEnumerator();
int i;
while (tmp.MoveNext()) {
      i = tmp.Current;
          {...} // your code
}

所以可以知道,只要我们实现了迭代器类和聚集类,那么就可以通过foreach来进行遍历了。

参考

1. How do foreach loops work in C#?

2. Foreach On IEnumerable

3. 详解C# 迭代器

4. .Net学习难点讨论系列11 - foreach与迭代器

时间: 2024-10-20 05:57:00

【迭代器模式在.NET中的应用】的相关文章

java集合类中的迭代器模式

不说模式的问题,看一个<<设计模式之禅>>里面的例子. 老板要看到公司了各个项目的情况.(我知道我这个概述很让人头大,看代码吧) 示例程序 v1 package Iterator; /** * @author cbf4Life [email protected] * 定义一个接口,所有的项目都是一个接口 */ public interface IProject { //从老板这里看到的就是项目信息 public String getProjectInfo(); } package

Java设计模式8:迭代器模式

迭代器模式 迭代器模式又叫做游标(Cursor)模式,其作用是提供一种方法访问一个容器元素中的各个对象,而又不暴露该对象的内部细节. 迭代器模式结构 迭代器模式由以下角色组成: 1.迭代器角色 负责定义访问和遍历元素的接口 2.具体迭代器角色 实现迭代器接口,并要记录遍历中的当前位置 3.容器角色 负责提供创建具体迭代器角色的接口 4.具体容器角色 实现创建具体迭代器角色的接口,这个具体迭代器角色与该容器的结构相关 迭代器模式在JDK中的应用及解读 迭代器模式就不自己写例子了,直接使用JDK中的

Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]

容器的主要职责有两个:存放元素和浏览元素.根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器. 用迭代器封装对动态数组的遍历:  1 2{<HeadFirst设计模式>之迭代器模式 } 3{ 容器中的元素类                  } 4{ 编译工具:Delphi7.0             } 5{ E-Mail :[email protected]     } 6 7unit uItem; 8 9interface1011type12  TMenuIte

Java设计模式之迭代器模式

概论 什么是迭代器模式?迭代器模式是提供一种方法访问一个容器对象中的各个元素,而又不需要暴露该对象的细节. 迭代器模式示例 迭代器模式中分为4种角色. ①抽象迭代器 ②具体迭代器 ③抽象容器 ④具体容器 首先我们一个抽象迭代器,抽象迭代器中包含遍历到下一个元素.判断遍历是否已经到了尾部.删除当前指向的元素. 1 public interface Iterator { 2 3 public Object next(); 4 public boolean hasNext(); 5 public bo

23种设计模式中的迭代器模式

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个对象. 那么如何提供一个方法顺序呢? public interface Iterator<T>{ public boolean hasNext(); public T next(); } public class XXX{ private List<XXX> list =new ArrayList<>(); public Iterator getIterator (){ return new XXXIterator()

php中的设计模式之--迭代器模式

<?php /** 迭代器模式 :迭代器(Iterator)模式,又叫做游标(Cursor)模式.GOF给出的定义为: 提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节. 迭代器模式是为容器而生.很明显,对容器对象的访问必然涉及到遍历算法.你可以一股脑的将遍历方法塞到容器对象中去: 或者根本不去提供什么遍历算法,让使用容器的人自己去实现去吧. (1) 需要一个容器 (2) 遍历方法即可 迭代器模式由以下角色组成: 1) 迭代器角色(Iterator):迭

迭代器模式(think in java中的设计模式)

迭代器模式:用来迭代一个容器集合数组的一种模式.可能大家很多时候是用for循环进行迭代的,但是实际上for循环内部不能使用remove方法,但是迭代器可以,这是因为迭代器内部进行了该方法的逻辑处理.同样我们也可以用到迭代器模式去迭代,他很好的封装了迭代方法.我们还可以从中进行一些特特异的迭代选取功能,比如迭代数字的字符串但是返回尾数为13579的数字for循环内部的东西可以封装在迭代器中.代码如下 public class Test2 { @Test public void t() { Coll

Java中的迭代器模式

迭代器模式 提供一种方式去访问一个容器元素中的各个对象,而又不暴露该对象的内部细节. 迭代器模式的结构 1.迭代器角色 负责定义访问和遍历元素的接口 2.具体迭代器角色 实现迭代器接口,并要记录遍历中的当前位置 3.容器角色 负责提供创建具体迭代器角色的接口 4.具体容器角色 实现创建具体迭代器角色的接口,这个具体迭代器角色与该容器的结构相关 为什么需要迭代器模式 列举一个简单的示例,遍历ArrayList.LinkedList.HashSet中各个元素: 1 public static voi

JavaScript设计模式 - 迭代器模式

迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示. 迭代器模式可以把迭代的过程从业务逻辑中分离出来,在使用迭代器模式之后,即使不关心对象的内部构造,也可以按顺序访问其中的每个元素 许多浏览器都支持 Javascript 的 Array.prototype.forEach 迭代器可以分为 内部迭代器 和 外部迭代器 一.jQuery 中的迭代器 1 $.each( [1,2,3,4], function (i, n) { 2 console.log( "当