1

今日、私は DynamicMethod クラスについて学び始めました。学習のために、DynamicMethod を使用して、引数を取らず、常にブール値を返す関数を作成することにしましたtrue

これを行う関数を C# で作成し、結果の IL コードを Telerik JustDecompile で調べました。

.method public hidebysig instance bool ReturnTrue1 () cil managed 
{
    .locals init (
        [0] bool CS$1$0000
    )

    IL_0000: nop
    IL_0001: ldc.i4.1
    IL_0002: stloc.0
    IL_0003: br.s IL_0005

    IL_0005: ldloc.0
    IL_0006: ret
}

シンプルに見えます。ドキュメントによると、これらの命令は単に整数 1 をスタックに配置して返すように見えます。

これまで見てきたいくつかの例に沿って、次のコンソール アプリケーションを作成しました。

using System;
using System.Reflection.Emit;

namespace EntityFrameworkDynamicMethod
{
    class Program
    {
        static void Main(string[] args)
        {            
            ReturnTrue ReturnTrueDelegate = GetReturnTrueDelegate();
            ReturnTrueDelegate();            
        }        

        delegate bool ReturnTrue();

        static ReturnTrue GetReturnTrueDelegate()
        {            
            DynamicMethod method = new DynamicMethod("ReturnTrue", typeof(bool), new Type[] {});
            ILGenerator generator = method.GetILGenerator();
            Label IL_0005 = generator.DefineLabel();
            generator.Emit(OpCodes.Nop);
            generator.Emit(OpCodes.Ldc_I4_1);
            generator.Emit(OpCodes.Stloc_0);            
            generator.Emit(OpCodes.Ldloc_0, IL_0005);            
            generator.MarkLabel(IL_0005);
            generator.Emit(OpCodes.Ret);

            return (ReturnTrue)method.CreateDelegate(typeof(ReturnTrue));
        }
    }
}

ただし、このコードを実行すると、次の例外が発生しますReturnTrueDelegate();

System.Security.VerificationException: Operation could destabilize the runtime.
at ReturnTrue()

この例外は何を意味し、これを修正するにはどうすればよいですか?

4

1 に答える 1

4
generator.Emit(OpCodes.Ldloc_0, IL_0005);

これは正しくありません。命令には引数がldloc.0ありません (もしかしてbr.s?)。
また、local 0 を宣言せずに使用することはできません。

ただし、その必要はありません。必要なことは、ロード1( ldc.i4.1) して返す ( ret) だけです。
リリース モードのコードを逆コンパイルすると、それがわかるはずです。

于 2013-08-11T02:18:05.107 に答える