您的位置:首页 > 其它

设计模式之三:迭代器模式(IteratorPattern)

2012-03-02 16:49 686 查看
迭代器(Iterator)模式,又叫游标(Cursor)模式。其定义为:提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式是和容器相关的,对容器对象的访问设计到遍历算法。

迭代器模式由以下角色组成:

迭代器角色(Iterator):迭代器角色负责定义访问和遍历元素的接口。

具体迭代器角色(Concrete Iterator):具体迭代器角色要实现迭代器接口,并记录遍历中的当前位置。

容器角色(Container):容器角色负责提供创建具体迭代器角色的接口。

具体容器角色(Concrete Container):具体容器角色实现创建具体迭代器角色的接口---这个迭代器角色与该容器的结构相关。

意图:就是提供一种访问集合对象的方法,而又无需暴露该对象的内部细节。

在.NET中的Iterator模式

在.NET下实现的Iterator模式,对于聚集接口和迭代器接口已经存在了,其中IEnumerator扮演的就是迭代器的角色。它的代码如下:

public interface IEnumerator

{

object Current

{

get;

}

void Reset();

bool MoveNext();

}

IEnumerable则扮演的就是抽象聚集的角色,只有一个GetEnumertor()方法。如果集合对象需要具备迭代遍历的功能,就必须实现该接口。

public interface IEnumerable

{

IEnumerator GetEnumerator();

}

下面看一个在网上http://www.theserverside.net/看到的.NET1.1下的迭代器例子,我稍微做了修改,Person类是一个可枚举的类。PersonsEnumerator类是一个枚举器类

public class Persons : IEnumerable

{

public string[] m_Names;

public Persons(string[] names)

{

m_Names = new string[names.Length];

names.CopyTo(m_Names, 0);

}

private string this[int index]

{

get

{

return m_Names[index];

}

set

{

m_Names[index] = value;

}

}

public IEnumerator GetEnumerator()

{

return new PersonsEnumerator(this);

}

}

public class PersonsEnumerator : IEnumerator

{

private int index = -1;

private Persons p;

public PersonsEnumerator(Persons p)

{

this.p = p;

}

public bool MoveNext()

{

if (index < p.m_Names.Length)

{

return true;

}

return false;

}

public void Reset()

{

index = -1;

}

public object Current

{

get

{

return p.m_Names[index];

}

}

}

在.NET2.0及以后的版本,由于有了yield return关键字,实现起来就更简单了:

public class Persons : IEnumerable

{

private string[] m_names;

public Persons(string[] names)

{

m_names = new string[names.Length];

names.CopyTo(m_names,0);

}

public IEnumerator GetEnumerator()

{

foreach(string name in m_names)

{

yield return name;

}

}

}

另外顺便简单介绍一下yield关键字:

关键字yield,在迭代器块中用于向枚举数对象提供值或发出迭代结束信号。迭代器有两个特殊语句:yield return <expression>;

Yield break;

迭代器块

迭代器块是有一个或多个yield语句的代码库。下面三种类型的代码块中任意一种都可以是迭代器块:

方法主体

访问器主体

运算符主体

Yield语句只能出现在迭代器块中,该块可用作方法,运算符或访问器的体。这类方法,运算符或访问器的体受以下约束的控制:

不允许不安全块

方法,运算符或访问器的参数不能是ref或out

Yield语句不能出现在匿名方法中

Yield return语句不能出在catch块中活含有一个或多个Catch子句的的try块中。

Yield语句的跌代块可以产生IEnumerator和IEnumerable两种对象:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: