为什么我不能将DynamicMethod绑定到struct实例?

时间:2011-10-27 15:22:50

标签: c# reflection.emit dynamicmethod

DynamicMethods允许您为您创建的委托指定目标实例。但是,当您使用结构类型时,这似乎不起作用。它失败,异常告诉我它无法绑定到此方法。错误是因为我的IL没有取消打包目标实例吗?

如果我将A更改为类,它可以正常运行。我究竟做错了什么? (另请不要建议调用Delegate.CreateDelegate绑定到目标实例的GetType方法)

以下是一个示例repro:

struct A { }
... //then some where in code::
Func<Type> f = CodeGen.CreateDelegate<Func<Type>>(il=>
    il.ldarga_s(0)
    .constrained(typeof(A))
    .callvirt(typeof(object).GetMethod("GetType"))
    .ret(),
    name:"Constrained",
    target:new A()
);

注意:我正在使用Emitted库来获取IL的流畅界面。这也是CodeGen方法的代码。

public static class CodeGen
{
    public static TDelegate CreateDelegate<TDelegate>(Action<ILGenerator> genFunc, string name = "", object target = null, bool restrictedSkipVisibility = false)
        where TDelegate:class
    {
        ArgumentValidator.AssertGenericIsDelegateType(() => typeof(TDelegate));
        ArgumentValidator.AssertIsNotNull(() => genFunc);

        var invokeMethod = typeof(TDelegate).GetMethod("Invoke");
        var @params = invokeMethod.GetParameters();
        var paramTypes = new Type[@params.Length + 1];
        paramTypes[0] = target == null ? typeof(object) : target.GetType();
        @params.ConvertAll(p => p.ParameterType)
            .CopyTo(paramTypes, 1);
        var method = new DynamicMethod(name ?? string.Empty, invokeMethod.ReturnType, paramTypes, restrictedSkipVisibility);
        genFunc(method.GetILGenerator());

        return method.CreateDelegate<TDelegate>(target);
    }
}

1 个答案:

答案 0 :(得分:0)

请参阅http://msdn.microsoft.com/en-us/library/74x8f551.aspx上的重要提示,这也适用于此处:

  

如果方法是静态的(在Visual Basic中为Shared)及其第一个参数   是Object或ValueType类型,然后firstArgument可以是一个值   类型。在这种情况下,firstArgument会自动装箱。自动   任何其他参数都不会发生拳击,就像它在C#中一样   Visual Basic函数调用。

这意味着动态方法的第一个参数需要是object类型,在进行约束调用之前,您需要先执行ldarg_0后跟一个unbox。

相关问题