DynamicMethod和out-parameters?

ang*_*son 9 c# out-parameters dynamicmethod

如何为具有out-parameter 的委托定义DynamicMethod ,如下所示?

public delegate void TestDelegate(out Action a);
Run Code Online (Sandbox Code Playgroud)

假设我只想要一个将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);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我明白了:

VerificationException was unhandled:
Operation could destabilize the runtime.
Run Code Online (Sandbox Code Playgroud)

del(out a);行了.

请注意,如果我注释掉在堆栈上加载null并尝试将其存储到参数中的两行,则该方法将无异常地运行.


编辑:这是最好的方法吗?

il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stind_Ref);
Run Code Online (Sandbox Code Playgroud)

Sam*_*ell 9

一种out说法仅仅是一个ref与参数OutAttribute应用到参数.

要存储到by-ref参数,您需要使用stind操作码,因为参数本身是指向对象实际位置的托管指针.

ldarg.0
ldnull
stind.ref
Run Code Online (Sandbox Code Playgroud)