当前位置:  开发笔记 > 编程语言 > 正文

这个编译器生成的枚举器是什么意思?

如何解决《这个编译器生成的枚举器是什么意思?》经验,为你挑选了1个好方法。

我写了一个相当复杂的yield-returns方法IEnumerable,但是当我在Reflector中检查编译器输出时,我并不了解编译器生成的实现的特定部分IEnumerator:

void IDisposable.Dispose()
{
    switch (this.<>1__state)
    {
        case 1:
        case 2:
        case 3:
            switch (this.<>1__state) // empty switch! why?!
            {
            }
            break;

        default:
            return;
            try   // What?! AFTER return?!
            {
            }
            finally // is the try-finally block anyhow relevant?
            {
                this.<>m__Finallya();
            }
            break;
    }
    this.<>m__Finally7();
}

我猜测(或希望)Reflector错位了外部的右支撑switch,并且它应该直接在后面return.不过,我不明白为什么在案例3中有一个空开关,或者为什么m__Finallya在一个finally块中被调用.(正常运行和finally块内部之间是否存在语义差异?除了CER之外,我的代码中没有.)

作为参考,这是IL:

.method private hidebysig newslot virtual final 
        instance void  System.IDisposable.Dispose() cil managed
{
  .override [mscorlib]System.IDisposable::Dispose
  // Code size       69 (0x45)
  .maxstack  2
  .locals init ([0] int32 CS$0$0000,
           [1] int32 CS$0$0001)
  IL_0000:  ldarg.0
  IL_0001:  ldfld      int32 FBD.TIP.Reader.MissingMessagesReader/'d__0'::'<>1__state'
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.1
  IL_0009:  sub
  IL_000a:  switch     ( 
                        IL_001c,
                        IL_001c,
                        IL_001c)
  IL_001b:  ret
  IL_001c:  ldarg.0
  IL_001d:  ldfld      int32 FBD.TIP.Reader.MissingMessagesReader/'d__0'::'<>1__state'
  IL_0022:  stloc.1
  IL_0023:  ldloc.1
  IL_0024:  ldc.i4.2
  IL_0025:  sub
  IL_0026:  switch     ( 
                        IL_0035,
                        IL_0035)
  IL_0033:  br.s       IL_003e
  .try
  {
    IL_0035:  leave.s    IL_003e
  }  // end .try
  finally
  {
    IL_0037:  ldarg.0
    IL_0038:  call       instance void FBD.TIP.Reader.MissingMessagesReader/'d__0'::'<>m__Finallya'()
    IL_003d:  endfinally
  }  // end handler
  IL_003e:  ldarg.0
  IL_003f:  call       instance void FBD.TIP.Reader.MissingMessagesReader/'d__0'::'<>m__Finally7'()
  IL_0044:  ret
} // end of method 'd__0'::System.IDisposable.Dispose

Jon Skeet.. 5

你没有展示你的原始迭代器块是什么样的,但我对Reflector和编译器生成的代码的经验是它并不总是能够完全准确地反编译,因为编译器使用了一些没有等效的IL. C#.

我有一篇关于迭代器块实现的文章可能对你有所帮助,但我不会太担心编译代码的样子.在某些情况下,C#编译器几乎肯定会生成不必要的代码,因为这样可以使编译器更简单.迭代器块必须非常难以正确(它可能变得非常复杂,最后是块和迭代器处理)所以我认为仅仅信任JIT来优化掉生成的代码中的开关/大小写等不必要的位是合理的.



1> Jon Skeet..:

你没有展示你的原始迭代器块是什么样的,但我对Reflector和编译器生成的代码的经验是它并不总是能够完全准确地反编译,因为编译器使用了一些没有等效的IL. C#.

我有一篇关于迭代器块实现的文章可能对你有所帮助,但我不会太担心编译代码的样子.在某些情况下,C#编译器几乎肯定会生成不必要的代码,因为这样可以使编译器更简单.迭代器块必须非常难以正确(它可能变得非常复杂,最后是块和迭代器处理)所以我认为仅仅信任JIT来优化掉生成的代码中的开关/大小写等不必要的位是合理的.

推荐阅读
农大军乐团_697
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有