意图:提供一种方法可以顺序访问一个聚合对象的各个元素,而又不暴露该对象的内部表示。
别名:游标Cursor;
关键思想:把对列表的访问和遍历从列表中分离出来,并且放在一个迭代器中Iterator中。
Iterator负责跟踪当前元素的状态.Current,MoveNext();
在C#中,可以用迭代器来简化实现。
迭代器是 C# 2.0 中的新功能。迭代器是方法、get 访问器或运算符,它使您能够在类或结构中支持 foreach 迭代,而不必实现整个IEnumerable 接口。您只需提供一个迭代器,即可遍历类中的数据结构。当编译器检测到迭代器时,它将自动生成 IEnumerable 或IEnumerable<T> 接口的 Current、MoveNext 和 Dispose 方法。
//非泛型实现,1)继承接口System.Collection.IEnumable2)实现public System.Collection.IEnumerator();
public class Data : System.Collection.IEnumable
{
string[] mData= {"1","2"};
public System.Collection.IEnumerator()
{
for (int i=0; i< mData.Length;i++)
yield return mData[i];
yield 关键字用于指定返回的值。到达 yield return 语句时,会保存当前位置。下次调用迭代器时将从此位置重新开始执行。
yield运行直到Code Block结束,或者遇到yield break(停止信号);
}
}
//泛型实现
1)继承System.Collections.Generic.IEnumerable<T>
2)实现泛型接口public IEnumerator<T> GetEnumerator()
3)实现非泛型GetEnumerator,因为 IEnumerable<T> 继承自 IEnumerable,非泛型方法直接将调用转给泛型方法。
public class Stack<T> : System.Collections.Generic.IEnumerable<T>
{
private List<T> mData = new List<T>();
public IEnumerator<T> GetEnumerator()
{
for (int i = 0; i < mData.Count; i++)
yield return mData[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public void Add(T t)
{
mData.Add(t);
}
}
Stack<string> intT = new Stack<string>();
intT.Add("1");
intT.Add("2");
foreach(var d in intT)
{
Console.WriteLine(d);
}
Stack<int> intT2 = new Stack<int>();
intT2.Add(1);
intT2.Add(2);
foreach(var e in intT2)
{
Console.WriteLine(e);
}