class IteratorWorkflow
{
static readonly string Padding = new string(' ', 30);
static IEnumerable<int> CreateEnumerable()
{
Console.WriteLine("{0}Start of CreateEnumerable()", Padding);
for (int i = 0; i < 3; i++) //当i =3 退出循环
{
Console.WriteLine("{0}About to yield {1}", Padding, i);
yield return i; //这句就退出函数了 返回MoveNext
Console.WriteLine("{0}After yield", Padding); //MoveNext函数调用执行这句
}
Console.WriteLine("{0}Yielding final value", Padding);
yield return -1; //MoveNext函数执行完
Console.WriteLine("{0}End of GetEnumerator()", Padding); //MoveNext函数 执行这句
}
static void Main() //显示迭代器及其调用者之间的调用序列
{
IEnumerable<int> iterable = CreateEnumerable();
IEnumerator<int> iterator = iterable.GetEnumerator();
Console.WriteLine("Starting to iterate");
while (true)
{
Console.WriteLine("Calling MoveNext()...");
bool result = iterator.MoveNext(); //调用CreateEnumerable()
Console.WriteLine("... MoveNext result={0}", result);
if (!result) //result为 false 推出循环
{
break;
}
Console.WriteLine("Fetching Current...");
Console.WriteLine("... Current result={0}", iterator.Current);
}
}
}
1 第一次调用MoveNext之前,CreateEnumerable中的代码不会调用
2 所有工作在调用MoveNext时完成了,获取Current的值不会执行任何代码
3 yield return 的位置,代码会停止运行,在下一次调用MoveNext时又继续执行
4 在一个方法中的不同地方可以编写多个yield return 语句
5 代码不会在最后的yield return处结束,而是通过返回false的 MoveNext调用来结束方法的执行
输出
Starting to iterate //开始迭代
Calling MoveNext()... //调用 MoveNext
Start of CreateEnumerable() //CreateEnumerable的开始
About to yield 0 //yield return0
... MoveNext result=True
Fetching Current... //取回 Current
... Current result=0
Calling MoveNext()...
After yield // yield之后
About to yield 1 //返回yield1
... MoveNext result=True
Fetching Current...
... Current result=1
Calling MoveNext()...
After yield
About to yield 2
... MoveNext result=True
Fetching Current...
... Current result=2
Calling MoveNext()...
After yield
Yielding final value
... MoveNext result=True
Fetching Current...
... Current result=-1
Calling MoveNext()...
End of GetEnumerator()
... MoveNext result=False