C#面向对象设计模式纵横谈 学习笔记18 Iterator迭代器模式(行为型模式)
2008-09-24 00:53
459 查看
迭代器模式我们在平时的开发中应该经常用到。不直接使用也会间接使用,我们使用foreach语句来循环就是在间接的使用迭代器模式
迭代器就像指针一样可以向前向后移动,在.net中迭代器只能向后移动.
动机:
在软件的构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。
意图:
提供一种方法顺序访问一个集合对象中的各个元素,而不暴露该对象的内部表示。
/// <summary>
/// 可迭代接口
/// </summary>
public interface IEnumerable
{
//得到迭代器
IEnumerator GetEnumerator();
}
/// <summary>
/// 迭代器接口
/// </summary>
public interface IEnumerator
{
//得到当前的对象
object Current
{
get;
}
bool MoveNext();
void Reset();
}
/// <summary>
/// 集合类型,实现了可迭代接口
/// </summary>
public class MyCollection : IEnumerable
{
internal int[] items;
public MyCollection()
{
items = new int[5] {1, 2, 3, 4, 5};
}
#region IEnumerable 成员
//实现迭代接口,返回迭代器
public IEnumerator GetEnumerator()
{
//在这里进行解藕,将集合对象转换为迭代器
return new MyEnumerator(this);
}
#endregion
}
//迭代器对象,实现了迭代器接口
internal class MyEnumerator : IEnumerator
{
private int nIndex;
MyCollection collection;
//构造函数将集合类型转换成内部成员
public MyEnumerator(MyCollection coll)
{
this.collection = coll;
nIndex = -1;
}
#region IEnumerator 成员
//返回当前迭代到的对象
public object Current
{
get
{
return collection.items[nIndex];
}
}
//移动到下一个对象,指针向后移动
public bool MoveNext()
{
nIndex++;
return (nIndex < collection.items.GetLength(0));
}
//重设迭代器,指针回零
public void Reset()
{
nIndex = -1;
}
#endregion
}
很清楚,在上面的代码中,我们通过GetEnumerator方法,将集合对象转换为了可迭代对象,这实际上是在对集合对象进行抽象,将他转换为迭代器。在这里,我们需要定义一个迭代器类,但是这是.net 1.1中的做法,在.net 2.0以后实现一个可迭代模式更加简单
/// <summary>
/// 集合类型,实现了可迭代接口
/// </summary>
public class MyCollection : IEnumerable<int>
{
internal int[] items;
public MyCollection()
{
items = new int[5] {1, 2, 3, 4, 5};
}
#region IEnumerable<int> 成员
public IEnumerator<int> GetEnumerator()
{
for(int i = 0; i < items.Length; i++)
{
yield return items[i];
}
}
#endregion
#region IEnumerable 成员
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
for(int i = 0; i < items.Length; i++)
{
yield return items[i];
}
}
#endregion
}
我们通过yield return关键字来返回一个IEnumerator接口,这个关键在在编译之后会自动生成对应的迭代器的代码。
在.net中迭代器只能先前,在c++中可以向后等其他操作。
注意:在迭代的过程中,我们不能向集合添加内容,后移除集合里的item,这样将会导致一些问题的出现
迭代器就像指针一样可以向前向后移动,在.net中迭代器只能向后移动.
动机:
在软件的构建过程中,集合对象内部结构常常变化各异。但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历”也为“同一种算法在多种集合对象上进行操作”提供了可能。使用面向对象技术将这种遍历机制抽象为“迭代器对象”为“应对变化中的集合对象”提供了一种优雅的方式。
意图:
提供一种方法顺序访问一个集合对象中的各个元素,而不暴露该对象的内部表示。
/// <summary>
/// 可迭代接口
/// </summary>
public interface IEnumerable
{
//得到迭代器
IEnumerator GetEnumerator();
}
/// <summary>
/// 迭代器接口
/// </summary>
public interface IEnumerator
{
//得到当前的对象
object Current
{
get;
}
bool MoveNext();
void Reset();
}
/// <summary>
/// 集合类型,实现了可迭代接口
/// </summary>
public class MyCollection : IEnumerable
{
internal int[] items;
public MyCollection()
{
items = new int[5] {1, 2, 3, 4, 5};
}
#region IEnumerable 成员
//实现迭代接口,返回迭代器
public IEnumerator GetEnumerator()
{
//在这里进行解藕,将集合对象转换为迭代器
return new MyEnumerator(this);
}
#endregion
}
//迭代器对象,实现了迭代器接口
internal class MyEnumerator : IEnumerator
{
private int nIndex;
MyCollection collection;
//构造函数将集合类型转换成内部成员
public MyEnumerator(MyCollection coll)
{
this.collection = coll;
nIndex = -1;
}
#region IEnumerator 成员
//返回当前迭代到的对象
public object Current
{
get
{
return collection.items[nIndex];
}
}
//移动到下一个对象,指针向后移动
public bool MoveNext()
{
nIndex++;
return (nIndex < collection.items.GetLength(0));
}
//重设迭代器,指针回零
public void Reset()
{
nIndex = -1;
}
#endregion
}
很清楚,在上面的代码中,我们通过GetEnumerator方法,将集合对象转换为了可迭代对象,这实际上是在对集合对象进行抽象,将他转换为迭代器。在这里,我们需要定义一个迭代器类,但是这是.net 1.1中的做法,在.net 2.0以后实现一个可迭代模式更加简单
/// <summary>
/// 集合类型,实现了可迭代接口
/// </summary>
public class MyCollection : IEnumerable<int>
{
internal int[] items;
public MyCollection()
{
items = new int[5] {1, 2, 3, 4, 5};
}
#region IEnumerable<int> 成员
public IEnumerator<int> GetEnumerator()
{
for(int i = 0; i < items.Length; i++)
{
yield return items[i];
}
}
#endregion
#region IEnumerable 成员
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
for(int i = 0; i < items.Length; i++)
{
yield return items[i];
}
}
#endregion
}
我们通过yield return关键字来返回一个IEnumerator接口,这个关键在在编译之后会自动生成对应的迭代器的代码。
在.net中迭代器只能先前,在c++中可以向后等其他操作。
注意:在迭代的过程中,我们不能向集合添加内容,后移除集合里的item,这样将会导致一些问题的出现
相关文章推荐
- C#面向对象设计模式纵横谈 学习笔记15 Command命令模式(行为型模式)
- [导入]C#面向对象设计模式纵横谈(18):(行为型模式) Iterator 迭代器模式.zip(8.04 MB)
- C#面向对象设计模式纵横谈 学习笔记21 Memento备忘录模式(行为型模式)
- C#面向对象设计模式纵横谈 学习笔记2 Singleton单例模式
- Design Pattern学习笔记之迭代器模式和复合模式(the Iterator and Composite Pattern)
- C#面向对象设计模式纵横谈 学习笔记16 Interpreter 解释器模式(行为型模式)
- 步步为营 .NET 设计模式学习笔记 十一、Iterator(迭代器模式)
- C#面向对象设计模式纵横谈 学习笔记14 Template Method模板方法(行为型模式)
- C#面向对象设计模式纵横谈 学习笔记20 Chain of Responsibility职责链模式(行为型模式)
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 设计模式学习笔记---迭代器模式iterator pattern(Java版)
- C#面向对象设计模式纵横谈 学习笔记4 Builder 生成器(创建型模式)
- C#面向对象设计模式纵横谈 学习笔记6 Prototype 原型(创建型模式)
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 设计模式笔记(18)---迭代器模式(行为型)
- C#面向对象设计模式纵横谈 学习笔记17 Mediator 中介者模式(行为型模式)
- 设计模式C++学习笔记之十四(Iterator迭代器模式)
- 【设计模式】学习笔记12:迭代器模式(Iterator)
- 设计模式笔记(18)---迭代器模式(行为型)
- 设计模式笔记(18)---迭代器模式(行为型)