迭代器的工作流程
namespace 迭代器
{
class Program
{
static readonly string padding=new string(' ',30);
static IEnumerable<int> GetEnumerable()
{
Console.WriteLine("{0}Start of GetEnumerable()",padding);
for(int i=0;i<3;i++)
{
Console.WriteLine("{0}About to yield{1}",padding,i);
yield return i;//在调用到 yield return位置时,代码就停止执行,在下一次调用MoveNext的时候又继续执行
Console.WriteLine("{0}After yield",padding);
}
Console.WriteLine("{0}Yielding final value",padding);
yield return -1;
Console.WriteLine("{0}End of GetEnumerator()",padding);
}
static void Main(string[] args)
{
IEnumerable<int> iterable = GetEnumerable();
IEnumerator<int> iterator = iterable.GetEnumerator();
Console.WriteLine("starting to iterate");
while(true)
{
Console.WriteLine("Calling MoveNext()...");
bool result = iterator.MoveNext();//每次调用MoveNext时,在提供下一个值之前(换句话说,就是执行到yield return语句之前),它需要执行GetEnumerator方法中的代码
Console.WriteLine("...MoveNext result={0}",result);
if(!result)
{
break;
}
Console.WriteLine("Fetching Current...");
Console.WriteLine("...Current result={0}",iterator.Current);
}
Console.ReadLine();
}
}
}
演示yield break的用法(提早退出)也演示了在迭代器块中使用方法参数的方式,但是迭代器代码块不能实现具有ref或out参数的方法
<pre name="code" class="csharp"> class Program
{
static IEnumerable<int> CountWithTimeLimit(DateTime limit)
{
for(int i=0;i<=100;i++)
{
if(DateTime.Now>=limit)
{
yield break;
}
yield return i;
}
}
static void Main(string[] args)
{
DateTime stop = DateTime.Now.AddSeconds(2);
foreach(int i in CountWithTimeLimit(stop))//<span style="font-family: Arial, Helvetica, sans-serif;">演示了在迭代器块中使用方法参数的方式,但是迭代器代码块不能实现具有ref或out参数的方法</span>
{
Console.WriteLine("Received {0}", i);
Thread.Sleep(300);
}
Console.ReadLine();
}
}