还是打开IL代码瞧一瞧到底发生了什么吧
Main方法的IL代码:
?
- .method private hidebysig static void Main() cil managed {
- .entrypoint .maxstack 1
- .locals init ( [0] int32 i,
- [1] class [mscorlib]System.Collections.Generic.IEnumerator`1<int32> CS$5$0000) L_0000: call class [mscorlib]System.Collections.Generic.IEnumerable`1<int32> TestLambda.Program::WithYield()
- L_0005: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator() L_000a: stloc.1
- L_000b: br.s L_0020 L_000d: ldloc.1
- L_000e: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current() L_0013: stloc.0
- L_0014: ldloca.s i L_0016: call instance string [mscorlib]System.Int32::ToString()
- L_001b: call void [mscorlib]System.Console::WriteLine(string) L_0020: ldloc.1
- L_0021: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext() L_0026: brtrue.s L_000d
- L_0028: leave.s L_0034 L_002a: ldloc.1
- L_002b: brfalse.s L_0033 L_002d: ldloc.1
- L_002e: callvirt instance void [mscorlib]System.IDisposable::Dispose() L_0033: endfinally
- L_0034: call string [mscorlib]System.Console::ReadLine() L_0039: pop
- L_003a: ret .try L_000b to L_002a finally handler L_002a to L_0034
- }
这里没什么稀奇的,在上一篇我已经分析过了,foreach内部就是转换成调用迭代器的MoveNext()方法进行while循环。我浏览到WithYield()方法:










