{
static IEnumerable<int> FromTo(int from, int to)
while (from <= to)
{
yield return from++; //yield return是一个新的关键字,意义在下面做分析
}
}
static void Main(string[] args)
{
foreach (int i in FromTo(5, 10))
{
Console.WriteLine(i); //这个foreach使用前面那个FromTo输出5到10的几个数字
}
}
}
}
private static void Main(string[] args) { using (IEnumerator<int> enumerator1 = Program.FromTo(5, 10).GetEnumerator()) { while (enumerator1.MoveNext()) { int num1 = enumerator1.Current; Console.WriteLine(num1); } } } |
源程序中关于迭代器的代码则被编译成了:
private static IEnumerable<int> FromTo(int from, int to) { Program.<FromTo>d__0 d__1 = new Program.<FromTo>d__0(-2); d__1.<>3__from = from; d__1.<>3__to = to; return d__1; }
FromTo返回了一个类,这个类反编译的代码是:
[CompilerGenerated]
private sealed class <FromTo>d__0 : IEnumerable<int>, IEnumerable, IEnumerator<int>, IEnumerator, IDisposable
{
// Methods
[DebuggerHidden]
public <FromTo>d__0(int <>1__state);
private bool MoveNext();
[DebuggerHidden]
IEnumerator<int> IEnumerable<int>.GetEnumerator();
[DebuggerHidden]
IEnumerator IEnumerable.GetEnumerator();
[DebuggerHidden]
void IEnumerator.Reset();
void IDisposable.Dispose();
// Properties
int IEnumerator<int>.Current { [DebuggerHidden] get; }
object IEnumerator.Current { [DebuggerHidden] get; }
// Fields
private int <>1__state;
private int <>2__current;
public int <>3__from;
public int <>3__to;
public int from;
public int to;
}
类中GetEnumerator方法的代码为:
IEnumerator<int> IEnumerable<int>.GetEnumerator()
{
Program.<FromTo>d__0 d__1;
if (Interlocked.CompareExchange(ref this.<>1__state, 0, -2) == -2)
{
d__1 = this;
}
else
{
d__1 = new Program.<FromTo>d__0(0);
}
d__1.from = this.<>3__from;
d__1.to = this.<>3__to;
return d__1;
}
Interlocked.CompareExchange(ref this.<>1__state, 0, -2) == -2是比较当前state(状态)是否为-2,如果为-2则替换为0.
GetEnumerator的作用是得到一个初始化了得迭代器实例,状态代码(state)为0.
然后就是MoveNext方法:
private bool MoveNext()
{
switch (this.<>1__state)
{
case 0:
{
this.<>1__state = -1;
while (this.from <= this.to)
{
this.<>2__current = this.from++;
this.<>1__state = 1;
return true;
Label_004A:
this.<>1__state = -1;
}
break;
}
case 1:
{
goto Label_004A;
}
}
return false;
}
每次执行MoveNext会改变迭代器中的Current量.
而yield return就是在每次MoveNext后返回迭代器中的Current