概述øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
意图øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
提供一种方法顺序访问一个聚合对象中各个元素, 而又不需暴露该对象的内部表示。[GOF 《设计模式》]øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
结构图øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
Iterator模式结构图如下:øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

图1 øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
Iterator模式结构图

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
生活中的例子øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
迭代器提供一种方法顺序访问一个集合对象中各个元素,而又不需要暴露该对象的内部表示。在早期的电视机中,一个拨盘用来改变频道。当改变频道时,需要手工转动拨盘移过每一个频道,而不论这个频道是否有信号。现在的电视机,使用[后一个]和[前一个]按钮。当按下[后一个]按钮时,将切换到下一个预置的频道。想象一下在陌生的城市中的旅店中看电视。当改变频道时,重要的不是几频道,而是节目内容。如果对一个频道的节目不感兴趣,那么可以换下一个频道,而不需要知道它是几频道。øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

图2 øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
使用选频器做例子的Iterator模式对象图

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
Iterator模式解说øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
在面向对象的软件设计中,我们经常会遇到一类集合对象,这类集合对象的内部结构可能有着各种各样的实现,但是归结起来,无非有两点是需要我们去关心的:一是集合内部的数据存储结构,二是遍历集合内部的数据。面向对象设计原则中有一条是类的单一职责原则,所以我们要尽可能的去分解这些职责,用不同的类去承担不同的职责。Iterator模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明的访问集合内部的数据。下面看一个简单的示意性例子,类结构图如下:øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

图3 示例代码结构图

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
首先有一个抽象的聚集,所谓的聚集就是就是数据的集合,可以循环去访问它。它只有一个方法GetIterator()让子类去实现,用来获得一个迭代器对象。øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/**////øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
<summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/// 抽象聚集øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
///øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
</summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
interface IListøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    IIterator GetIterator();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

抽象的迭代器,它是用来访问聚集的类,封装了一些方法,用来把聚集中的数据按顺序读取出来。通常会有MoveNext()、CurrentItem()、Fisrt()、Next()等几个方法让子类去实现。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/**////øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
<summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/// 抽象迭代器øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
///øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
</summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
interface IIteratorøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
bool MoveNext();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    Object CurrentItem();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
void First();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
void Next();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

具体的聚集,它实现了抽象聚集中的唯一的方法,同时在里面保存了一组数据,这里我们加上Length属性和GetElement()方法是为了便于访问聚集中的数据。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/**////øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
<summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/// 具体聚集øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
///øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
</summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class ConcreteList : IListøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
int[] list;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public ConcreteList()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        list
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
newøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
int[] { 1,2,3,4,5};øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public IIterator GetIterator()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
returnøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
new ConcreteIterator(this);øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
int LengthøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
getøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{ return list.Length; }øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
int GetElement(int index)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
return list[index];øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

具体迭代器,实现了抽象迭代器中的四个方法,在它的构造函数中需要接受一个具体聚集类型的参数,在这里面我们可以根据实际的情况去编写不同的迭代方式。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/**////øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
<summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/// 具体迭代器øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
///øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
</summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class ConcreteIterator : IIteratorøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
private ConcreteList list;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
privateøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
int index;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public ConcreteIterator(ConcreteList list)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
this.list = list;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        index
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
0;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
bool MoveNext()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
if (index < list.Length)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
           
returnøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
true;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
elseøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
           
returnøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
false;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public Object CurrentItem()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
return list.GetElement(index) ;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
void First()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        index
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
0;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
void Next()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
if (index < list.Length)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
            index
++;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

简单的客户端程序调用:

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/**////øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
<summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
/// 客户端程序øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
///øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
</summary>øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class ProgramøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
staticøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
void Main(string[] args)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        IIterator iterator;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        IList list
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
new ConcreteList();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        iterator
= list.GetIterator();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
while (iterator.MoveNext())øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
           
int i = (int)iterator.CurrentItem();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
            Console.WriteLine(i.ToString());øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
            iterator.Next();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        Console.Read();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

一个简单的迭代器示例就结束了,这里我们并没有利用任何的.NET特性,在C#中,实现Iterator模式已经不需要这么麻烦了,已经C#语言本身就有一些特定的实现,下面会说到。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
.NET中的Iterator模式øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
在.NET下实现Iterator模式,对于聚集接口和迭代器接口已经存在了,其中IEnumerator扮演的就是迭代器的角色,它的实现如下:øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
interface IEumeratorøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
object CurrentøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
get;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
bool MoveNext();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
void Reset();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

属性Current返回当前集合中的元素,Reset()方法恢复初始化指向的位置,MoveNext()方法返回值true表示迭代器成功前进到集合中的下一个元素,返回值false表示已经位于集合的末尾。能够提供元素遍历的集合对象,在.Net中都实现了IEnumerator接口。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
IEnumerable则扮演的就是抽象聚集的角色,只有一个GetEnumerator()方法,如果集合对象需要具备跌代遍历的功能,就必须实现该接口。øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
interface IEnumerableøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    IEumerator GetEnumerator();øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

下面看一个在.NET1.1下的迭代器例子,Person类是一个可枚举的类。PersonsEnumerator类是一个枚举器类。这个例子来自于http://www.theserverside.net/,被我简单的改造了一下。

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class Persons : IEnumerable øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
string[] m_Names; øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public Persons(paramsøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
string[] Names) øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        m_Names
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
newøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
string[Names.Length]; øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        Names.CopyTo(m_Names,
0); øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
privateøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
stringøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
this[int index] øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
get øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
           
return m_Names[index]; øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
set øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
            m_Names[index]
= value; øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public IEnumerator GetEnumerator()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
returnøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
new PersonsEnumerator(this);øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class PersonsEnumerator : IEnumeratorøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
privateøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
int index =øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
-1;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
private Persons P;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
public PersonsEnumerator(Persons P)øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
this.P = P;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
bool MoveNext()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        index
++;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
return index < P.m_Names.Length;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
void Reset()øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        index
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
-1;øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
publicøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
object CurrentøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
getøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
           
return P.m_Names[index];øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

来看客户端代码的调用:

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
class Program øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
staticøÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
void Main(string[] args) øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
   
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        Persons arrPersons
=øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
new Persons("Michel","Christine","Mathieu","Julien"); øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
foreach (string s in arrPersons) øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
       
{ øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
            Console.WriteLine(s); øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
        Console.ReadLine(); øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
    }
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
}
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø

程序将输出:

øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
Michel øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
øÕc:Êg°ðÍwww.netcsharp.cn¥3³á¢íÔø
Christine øÕc:Êg°ð