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

时间:2010-06-13 05:19:50

标签: c# .net reflection reflection.emit

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

这样的代码
loadedType = typeBuilder.CreateType();
myDelegate = (MyDelegate)Delegate.CreateDelegate(
                                  typeof(MyDelegate), methodBuilder);

将methodBuilder重用为methodInfo,我得到异常“MethodInfo必须是RuntimeMethodInfo”。现在通常我可以用

重新获取MethodInfo
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 个答案:

答案 0 :(得分:3)

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

方法的重载区别在于其参数列表,因此我猜您需要在methodBuilder上调用GetParameters,然后将返回的ParameterInfo[]数组转换为{ {1}}数组传递给appropriate GetMethod overload

Type[]

答案 1 :(得分:0)

您需要使用带有一系列类型的GetMethod重载。选择方法重载以通过传递给它们的参数进行绑定。由于在通过反射获取元数据时实际上并未调用方法,因此必须提供Type对象的有序数组以获取正确的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);

请记住,返回类型不是方法签名的一部分,只有方法名称及其参数类型。