C#特性 迭代器(下) yield以及流的延迟计算

2019-12-26 11:17:15王冬梅

还是打开IL代码瞧一瞧到底发生了什么吧

Main方法的IL代码:
 

  1. .method private hidebysig static void Main() cil managed  { 
  2.   .entrypoint    .maxstack 1 
  3.   .locals init (      [0] int32 i, 
  4.     [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() 
  5.   L_0005: callvirt instance class [mscorlib]System.Collections.Generic.IEnumerator`1<!0> [mscorlib]System.Collections.Generic.IEnumerable`1<int32>::GetEnumerator()    L_000a: stloc.1  
  6.   L_000b: br.s L_0020    L_000d: ldloc.1  
  7.   L_000e: callvirt instance !0 [mscorlib]System.Collections.Generic.IEnumerator`1<int32>::get_Current()    L_0013: stloc.0  
  8.   L_0014: ldloca.s i    L_0016: call instance string [mscorlib]System.Int32::ToString() 
  9.   L_001b: call void [mscorlib]System.Console::WriteLine(string)    L_0020: ldloc.1  
  10.   L_0021: callvirt instance bool [mscorlib]System.Collections.IEnumerator::MoveNext()    L_0026: brtrue.s L_000d 
  11.   L_0028: leave.s L_0034    L_002a: ldloc.1  
  12.   L_002b: brfalse.s L_0033    L_002d: ldloc.1  
  13.   L_002e: callvirt instance void [mscorlib]System.IDisposable::Dispose()    L_0033: endfinally  
  14.   L_0034: call string [mscorlib]System.Console::ReadLine()    L_0039: pop  
  15.   L_003a: ret     .try L_000b to L_002a finally handler L_002a to L_0034 
?

这里没什么稀奇的,在上一篇我已经分析过了,foreach内部就是转换成调用迭代器的MoveNext()方法进行while循环。我浏览到WithYield()方法: