class IteratorBlockIterationSample : IEnumerable
{
object[] values;
int startingPoint;
public IteratorBlockIterationSample(object[] values, int startingPoint) //实例化类的时候调用
{
this.values = values; // 一个是 a b c d e
this.startingPoint = startingPoint; // 3
}
public IEnumerator GetEnumerator() // 关键字 in 调用
{
for (int index = 0; index < values.Length; index++) // valuse.length= 5 执行完一次 index+1 index = 1
{
yield return values[(index + startingPoint) % values.Length]; // 返回values[3] values[4] values[0] [1] [2]
} //yield 告诉编译器迭代器块的方法,返回一个Ienumerator接口 返回的类型要和代码块的类型兼容
} //7行代码搞定 还有4行括号 替换整个IterationSampleiterator类
static void Main()
{
object[] values = { "a", "b", "c", "d", "e" };
IteratorBlockIterationSample collection = new IteratorBlockIterationSample(values, 3);
foreach (object x in collection)
{
Console.WriteLine(x); //输出 d 调用in 调用for 循环, 得到e,输出e 调用in 调用for, 输出 a b c
}
}
}
当编译器看到迭代器块的时候,会为状态机创建一个嵌套类型 来记录块中的位置以及局部变量的值。
要实现迭代器,状态机要做的事
1 具有某个初始状态
2 每次调用MoveNext时,提供下一个值之前(换句话说,就是执行到yield return语句之前),它需要
执行GetEnumerator方法中的代码
3 使用Current属性,它必须返回我们生成的上一个值
4 它必须知道何时完成生成值的操作,以便MoveNext返回False
输出
d
e
a
b
c