代码之家  ›  专栏  ›  技术社区  ›  Qwertie

Reflection.Emit:如何将MethodBuilder可靠地转换为RuntimeMethodInfo?

  •  3
  • Qwertie  · 技术社区  · 15 年前

    在动态生成一个类型并调用TypeBuilder.CreateType之后,我想创建一个指向新类型中方法的委托。但是如果我使用这样的代码

    loadedType = typeBuilder.CreateType();
    myDelegate = (MyDelegate)Delegate.CreateDelegate(
                                      typeof(MyDelegate), methodBuilder);
    

    将methodBuilder作为methodInfo重用,会出现异常“methodInfo必须是RuntimeMethodInfo”。现在通常我可以用

    MethodInfo mi = loadedType.GetMethod(methodBuilder.Name);
    myDelegate = (MyDelegate)Delegate.CreateDelegate(typeof(MyDelegate), mi);
    

    但是我的类可能包含几个同名的重载方法。如何确保我得到正确的答案?方法是否有可以在loadedType中查找的持久标识符?

    更新:好的,这是我用来重新获取MethodInfo的东西。我只希望我能确定它在任何情况下都能起作用。

    private static MethodInfo ReacquireMethod(Type type, MethodInfo method)
    {
        BindingFlags flags = BindingFlags.DeclaredOnly;
        flags |= (method.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic);
        flags |= (method.IsStatic ? BindingFlags.Static : BindingFlags.Instance);
        MethodInfo m = type.GetMethod(method.Name, flags, null,
                                              ParameterTypes(method), null);
        Debug.Assert(m != null);
        return m;
    }
    
    2 回复  |  直到 15 年前
        1
  •  3
  •   LukeH    15 年前

    据我所知,没有持久的共享标识符。

    方法的重载是通过参数列表来区分的,所以我猜您需要调用 GetParameters methodBuilder 然后翻译返回的 ParameterInfo[] 排列成一个 Type[] appropriate GetMethod overload :

    MethodInfo mi = loadedType.GetMethod(
        methodBuilder.Name,
        methodBuilder.GetParameters().Select(p => p.ParameterType).ToArray());
    
        2
  •  0
  •   jrista    15 年前

    您需要使用获取类型数组的GetMethod重载。方法重载是通过传递给它们的参数来选择绑定的。由于在通过反射获取方法的元数据时实际上没有调用方法,因此必须提供类型对象的有序数组才能获取正确的MethodInfo对象:

    Type.GetMethod Method (String, Type[])

    MethodInfo mi = loadedType.GetMethod(
        methodBuilder.Name, 
        new[] 
        { 
            typeof(string), 
            typeof(int) 
        }
    );
    

    Assiming methodBuilder.Name是“MyMethod”,它将绑定以下内容:

    public <returnType> MyMethod(string param1, int param2);