C#迭代器有很多值得学习的地方,这里我们主要介绍C#迭代器模式,包括介绍ICollection负责数据存储等方面。
提到C#迭代器我们不能不想到C#迭代器模式,那我就以C#迭代器模式作为开场白。
在我们的应用程序中常常有这样一些数据结构:
它们是一个数据的集合,如果你知道它们内部的实现结构就可以去访问它们,它们各自的内部存储结构互不相同,各种集合有各自的应用场合.说到这里大家可能想出一大堆这样的集合了:List,Hashtable,ArrayList等等。这些集合各自都有各自的个性,这就是它们存在的理由。但如果你想遍历它你必须知道它内部的存储细节,作为一个集合元素,把内部细节暴露出来肯定就不好了,这样客户程序就不够稳定了,在你更换集合对象的时候,比如List 不能满足需求的时候,你换成Hashtable,因为以前的客户程序过多的关注了List内部实现的细节,所以不能很好的移植。而C#迭代器模式就是为解决这个问题而生的:
提供一种一致的方式访问集合对象中的元素,而无需暴露集合对象的内部表示。
比如现在有这样一个需求,遍历集合内的元素,然后输出,但是并不限定集合是什么类型的集合,也就是未来集合可能发生改变。
思考:
集合会发生改变,这是变化点,集合改变了,遍历方法也改变,我们要保证遍历的方法稳定,那么就要屏蔽掉细节。找到了变化点那我们就将其隔离起来(一般使用interface作为隔离手段):假设所有的集合都继承自ICollection接口,这个接口用来隔离具体集合的,将集合屏蔽在接口后面,作为遍历我们肯定需要这样一些方法:MoveNext,Current,既然ICollection负责数据存储,职责又要单一,那么就新建立一个接口叫做 Iterator吧,每种具体的集合都有自己相对应的Iterator实现:
- public interface ICollection
- {
- int Count { get; }
- ///
- /// 获取迭代器
- ///
- /// 迭代器
- Iterator GetIterator();
- }
- ///
- /// 迭代器接口
- ///
- public interface Iterator
- {
- bool MoveNext();
- object Current { get; }
- }
- public class List : ICollection
- {
- private const int MAX = 10;
- private object[] items;
- public List()
- {
- items = new object[MAX];
- }
- public object this[int i]
- {
- get { return items[i]; }
- set { this.items[i] = value; }
- }
- #region ICollection Members
- public int Count
- {
- get { return items.Length; }
- }
- public Iterator GetIterator()
- {
- return new ListIterator(this);
- }
- #endregion
- }
- public class ListIterator : Iterator
- {
- private int index = 0;
- private ICollection list;
- public ListIterator(ICollection list)
- {
- this.list = list;
- index = 0;
- }
- #region Iterator Members
- public bool MoveNext()
- {
- if (index + 1 > list.Count)
- return false;
- else
- {
- index++;
- return true;
- }
- }
- public object Current
- {
- get { return list[index]; }
- }
- #endregion
- }
- ///
- /// 测试
- ///
- public class Program
- {
- static void Main()
- {
- ICollection list = new List();
- Iterator iterator = list.GetIterator();
- while (iterator.MoveNext())
- {
- object current = iterator.Current;
- }
- }
- }
【编辑推荐】