【问题标题】:Why can I not bind a DynamicMethod to a struct instance?为什么我不能将 DynamicMethod 绑定到结构实例?
【发布时间】:2011-12-16 14:58:39
【问题描述】:

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

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

这是一个示例复制:

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);
    }
}

【问题讨论】:

    标签: c# reflection.emit dynamicmethod


    【解决方案1】:

    请参阅http://msdn.microsoft.com/en-us/library/74x8f551.aspx 的重要说明,此处也适用:

    如果方法是静态的(在 Visual Basic 中是共享的)并且它的第一个参数 是 Object 或 ValueType 类型,那么 firstArgument 可以是一个值 类型。在这种情况下 firstArgument 被自动装箱。自动的 任何其他参数都不会发生装箱,就像在 C# 或 Visual Basic 函数调用。

    这意味着您的动态方法的第一个参数必须是object 类型,并且您需要先执行 ldarg_0,然后在执行受限调用之前取消框。

    【讨论】:

      猜你喜欢
      • 2018-09-23
      • 2012-01-17
      • 2012-07-16
      • 2011-12-04
      • 2010-10-04
      • 2013-05-29
      • 2023-01-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多