枚举聚合中的元素
之前我们写过这样的代码:
foreach极大简化了需要编写的代码,但是foreach只能在特定情况下使用-只能遍历可枚举集合.
什么是可枚举集合?就是实现了System.Collections.IEnumerable接口的集合
可以看到IEnumerable接口包含了一个名为GetEnumerator的方法:
GetEnumerator返回IEnumerator
也就是返回了实现了IEnumerator接口的枚举器对象
可将枚举器视为指向列表中的元素的指针.指针最开始指向第一个元素之前的位置。
调用MoveNext方法,就可以让指针移到列表中的下一项,移动成功返回true,否则返回false。
Current属性访问当前指向的项,Rest方法返回到指针第一项之前的位置。
使用集合的GetEnumerator方法创建枚举器,然后反复调用MoveNext方法,并获取Current属性的值,就可以每次在集合中移动一个元素的位置。这就是foreach语句做的事情。
为了创建自己的可枚举集合类,就必须在自己的集合类中实现IEnumerable接口,并提供IEnumerator该接口的一个实现.
以便由集合类的GetEnumerator方法返回.
下面来手动实现枚举器
代码如下:
static void InsertIntoTree<TItem>(ref Tree<TItem> tree, params TItem[] data) where TItem : IComparable<TItem>
{
foreach (TItem datum in data)
{
if (tree == null)
{
tree = new Tree<TItem>(datum);
}
else
{
tree.Insert(datum);
}
}
}
public class TreeEnumerator<TItem> : IEnumerator<TItem> where TItem : IComparable<TItem>
{
private Tree<TItem> currentData = null; //容纳对要枚举的树的引用
private TItem currentItem = default(TItem);//容纳Current属性返回的值,因为TItem是未知的,我们不知道用什么值来初始化它
//所以最好的方法就是使用default,如果是引用类型则为null,如果是数值就为0,如果是bool,则为false等等.
private Queue<TItem> enumData = null;// 用节点的值填充enumData队列
public TreeEnumerator(Tree<TItem> data) //构造器
{
this.currentData = data;
}