9

このように -パラメータを持つデリゲートの DynamicMethod を定義するにはどうすればよいoutですか?

public delegate void TestDelegate(out Action a);

メソッドを呼び出すときにa引数をに設定するメソッドが必要だとしましょう。null

これを処理するためのおそらくより良い方法は、メソッドがActionデリゲートを返すようにすることですが、これは大規模なプロジェクトの単純化された部分にすぎず、問題のメソッドは既に値を返しているため、outパラメーターを処理する必要があることに注意してください。それに加えて、したがって質問です。

私はこれを試しました:

using System;
using System.Text;
using System.Reflection.Emit;

namespace ConsoleApplication8
{
    public class Program
    {
        public delegate void TestDelegate(out Action a);

        static void Main(String[] args)
        {
            var method = new DynamicMethod("TestMethod", typeof(void),
                new Type[] { typeof(Action).MakeByRefType() });
            var il = method.GetILGenerator();

            // a = null;
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Starg, 0);

            // return
            il.Emit(OpCodes.Ret);

            var del = (TestDelegate)method.CreateDelegate(typeof(TestDelegate));
            Action a;
            del(out a);
        }
    }
}

しかし、私はこれを取得します:

VerificationException was unhandled:
Operation could destabilize the runtime.

ライン上del(out a);

スタックに null をロードし、それを引数に格納しようとする 2 行をコメント アウトすると、メソッドは例外なく実行されることに注意してください。


編集:これは最善のアプローチですか?

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
4

1 に答える 1

9

引数は、パラメータに が適用された単なるout引数ですrefOutAttribute

by-ref 引数に格納するには、オペコードを使用する必要がありますstind。これは、引数自体がオブジェクトの実際の場所へのマネージ ポインターであるためです。

ldarg.0
ldnull
stind.ref
于 2009-08-18T09:46:37.597 に答える