迭代器位置示意:
代码示例:
变量名没有完全与课程示例一致,换为更容易理解的变量名。
//自定义类,只有一个功能:可以被迭代
class ReadOnlyCollection : IEnumerable
{
//集合的内置数组
private int[] inputCollection;
public ReadOnlyCollection(int[] input)
{
this.inputCollection = input;
}
//实现接口IEnumerable中的方法,该方法要求返回一个迭代器
//这就是声明“内嵌迭代器类”的原因
public IEnumerator GetEnumerator()
{
return new Enumerator(this);
}
//迭代器类(内嵌类)
public class Enumerator : IEnumerator
{
//迭代器的功能就是迭代集合,必须跟集合一起才能形成迭代行为
//所以,迭代器必须拥有一个集合
//那么用哪个集合?既然这个迭代器是为ReadOnlyCollection类声明的,
//自然是ReadOnlyCollection类
//被迭代器迭代的集合
private ReadOnlyCollection readOnlyCollection;
//迭代器的位置
private int position;
//构造器
public Enumerator(ReadOnlyCollection collection)
{
this.readOnlyCollection = collection; //接收一个传入的集合,用作被迭代器迭代的集合
position = -1; //迭代器在集合中的起始位置,-1表示未开始迭代
}
//属性:返回集合中迭代器所处位置的元素
public object Current
{
get
{
//课程中老师提到的很有意思的现象:内嵌类可以访问外层类的私有字段
//因为内嵌类是外层类的成员
object obj = readOnlyCollection.inputCollection[position];
return obj;
}
}
//方法:判断迭代器是否后移一位
public bool MoveNext()
{
//position的初始值为-1,++position表示后移1位,也就是集合中“索引0”的位置
//为什么要++?
//如果不++,迭代器会多移动1次
//++为什么在前?
//++position整体作为一个表达式
//++position:先++,后提供值;position++:先提供值,后++
//判断:如果位置小于集合的长度,则位置后移,否则位置就不后移
if (++position < readOnlyCollection.inputCollection.Length)
{
return true;
}
else
{
return false;
}
}
//方法:重置迭代器位置
public void Reset()
{
//因为集合的元素索引从0开始,所以迭代器的位置应在第一个元素之前,
//也就是0的前面,-1
position = -1;
}
}
}
补充:
MoveNext方法中,更容易理解的写法是:
public bool MoveNext()
{
//集合的索引
int index = position + 1;
if (index < readOnlyCollection.inputCollection.Length)
{
return true;
}
else
{
return false;
}
}