迭代器模式是行为模式的一种范例,行为模式是一种简化对象之间通信的一种设计模式。在.NET中使用IEnumerator和IEnumerable接口及它们的泛型等价物来封装的,如果一个类型实现了IEnumerable接口,就说明它是可迭代的,调用GetEnumerator方法返回IEnumerator的实现,这是迭代器本身。
C#1使用foreach语句实现了访问迭代器的内置支持,foreach语句会被编译成使用GetEnumerator和MoveNext方法以及Current属性。C#中迭代器只能向后访问,而C++中迭代器可以支持前后访问。
背景,假设有一个关于学生的队列,每个学生依次报出自己的名字,
Student类如下:
[C#] 纯文本查看 复制代码 class Student
{
public string Name { get; set; }
public Student(string name)
{
Name = name;
}
public void SayName()
{
Console.WriteLine(Name);
}
}
有一个实现IEnumerable的Queue的泛型类,如下
[C#] 纯文本查看 复制代码 class Queue<T> : IEnumerable<T> where T : class
{
public List<T> objects = new List<T>();
public Queue(List<T> list)
{
objects = list;
}
//实现从IEnumerable中的GetEnumerator方法
/*
个人觉得这个方法在迭代中只会调用一次,不然每次都返回一个新的QueueIterator<T>对象,位置记录都会重置为-1
*/
public IEnumerator<T> GetEnumerator()
{
return new QueueIterator<T>(this);
}
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
使用GetEnumerator方法返回一个迭代器,而迭代器需要实现IEnumerator接口,如下
[C#] 纯文本查看 复制代码 class QueueIterator<T> : IEnumerator<T> where T : class
{
private ConsoleDemo.Chapter6.Queue<T> q = null;
int startPoint = -1; //用于保存游标的位置
public QueueIterator(ConsoleDemo.Chapter6.Queue<T> q)
{
this.q = q;
}
//返回合适位置上的T类型实例,这个例子中调用提这个自动属性
public T Current
{
get
{
if (startPoint==-1 || startPoint==q.objects.Count)
{
throw new InvalidOperationException();
}
int index = startPoint + q.objects.Count;
index = index % q.objects.Count;
return q.objects[index];
}
}
object IEnumerator.Current
{
get
{
if (startPoint == -1 || startPoint == q.objects.Count)
{
throw new InvalidOperationException();
}
int index = startPoint + q.objects.Count;
index = index % q.objects.Count;
return q.objects[index];
}
}
public void Dispose()
{
}
public bool MoveNext()
{
if (startPoint != q.objects.Count)
{
startPoint++;
}
return startPoint < q.objects.Count;
}
//当迭代结束后,会调用这个方法,则下一次迭代后重新从第一个位置开始
public void Reset()
{
startPoint = -1;
}
}
分别要去实现从IEnumerator中的Current属性、Dispose方法(有必要的话)、MoveNext方法、Reset方法。
|