質問

私は歩留まり-リターンがIEnumerable<string>が、私は反射でコンパイラの出力を検査するとき、私は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();
}

私は推測する(または期待して)反射器が外switchの閉じ括弧を紛失していること、そしてそれがreturn後に直接でなければならないことです。そこケース3内の空のスイッチがある、またはなぜm__Finallyafinallyブロックに呼ばれている理由それでも、私は理解していません。 (通常と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/'<GetMissingMessages>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/'<GetMissingMessages>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/'<GetMissingMessages>d__0'::'<>m__Finallya'()
    IL_003d:  endfinally
  }  // end handler
  IL_003e:  ldarg.0
  IL_003f:  call       instance void FBD.TIP.Reader.MissingMessagesReader/'<GetMissingMessages>d__0'::'<>m__Finally7'()
  IL_0044:  ret
} // end of method '<GetMissingMessages>d__0'::System.IDisposable.Dispose
役に立ちましたか?

解決

これは単に反射板は、(反復子ブロックは限りがIL有効であるように、「通常」のC#を関連付ける必要がないので)、生成されたILに追いつくために苦労しています。特に、retfinallyブロックの後である。

他のヒント

私はC#コンパイラは、(それはおそらく少しばかげているのです)、愚かであることを主張することができます。それは(すべてが嫌なゴミが省略されます)実行時でJITコンパイルされたときに、このコードは非常に異なって見えることも十分に可能です。

とにかく、ステートマシンと多分ご存知?もしC#(利回りのもの)で発電機を書くときには、ステートマシンとしてこのジェネレータを実装して匿名型を発するようにコンパイラに指示します。これは、検証可能であることを意味している素敵なフォーマルなアプローチです。それはおそらく、それはそれがない道に見える理由です。

scroll top