关于c#:如果我在一个封闭的泛型类型上有一个MethodInfo,那么有一种简单的方法来切换这些类型吗?

If I have a MethodInfo on a closed generic Type is there an easy way to switch those types?

比如说,我有一个类似于Nullable.HasValue的MethodInfo。有没有办法把它转换成Nullable.HasValue

我知道对于常规的泛型方法,我可以执行methodInfo.GetGenericMethod(),但我看不到从方法中为类型执行此操作的方法,而不需要执行更多的反射开销。如果我已经有了这个方法,为什么我要重新思考?

有趣的是,所有的方法都有相同的MetadataToken,这使得module.resolveMember似乎能够将正确的方法拉出更加令人印象深刻。

有没有办法用Module.ResolveMethod来做这个?本质上,方法和类型都可能有通用参数,我可能需要切换它们。因为MethodInfo总是说它的令牌是相同的,并且该令牌表示MethodInfo是该方法最开放的版本。我只是需要某种方法把它转换成我的类型。

编辑:更深入地说,对于像List.Add这样的东西,我从中检索的List.Add元数据令牌实际上是生活在我的模块中,而通用定义则生活在不同的模块中。

我真的不想在检索成员一次后再进行反射,因为很难解析正被调用的完全相同的方法。

好吧,也许我只是个傻瓜,但为什么这不起作用:

1
2
3
var methodinfo = typeof(List<int>).GetMethod("Add");
var handle = methodinfo.MetaDataToken;
var methodinfo2 = methodinfo.Module.ResolveMethod(handle,new []{typeof(string)},null);

为什么卫理公会说它是Add(T),而不是Add(string)


你可以用MethodBase.GetMethodFromHandle一行来完成,但要使用这种方法,你必须通过typeof(List),而不仅仅是typeof(string)

1
2
3
4
5
6
var methodinfo = typeof(List<int>).GetMethod("Add");
var methodinfo2 = MethodBase.GetMethodFromHandle(methodinfo.MethodHandle,
                                                 typeof (List<string>).TypeHandle);

Console.WriteLine(methodinfo);
Console.WriteLine(methodinfo2);

这个链接包括上面的示例和解释为什么ResolveMethod不起作用。

https://www.re-motion.org/blogs/mix/archive/2009/08/12/trying-to-resolve-a-method-in-a-closed-generic-type.aspx


你可以更仔细地思考一下。你不能不经思考就神奇地完成它。

1
2
3
4
5
6
7
8
9
10
11
12
13
    static void Main(string[] args)
    {
        PropertyInfo intHasValue = typeof (int?).GetProperty("HasValue");
        PropertyInfo boolHasValue = ChangeGenericType(intHasValue, typeof (bool));
    }

    public static PropertyInfo ChangeGenericType(PropertyInfo property, Type targetType)
    {
        Type constructed = property.DeclaringType;
        Type generic = constructed.GetGenericTypeDefinition();
        Type targetConstructed = generic.MakeGenericType(new[] {targetType});
        return targetConstructed.GetProperty(property.Name);
    }

当然,这只适用于具有单个类型参数的泛型类型,但如果需要,可以将其概括为执行更多操作。


解决了它。但最大的问题是这是一种安全的方法吗?这里有什么我可能做错的地方吗?

1
2
3
4
5
6
7
8
9
10
11
12
    public static MethodInfo Convert(this MethodInfo method,params Type[] DeclaringTypeArguments)
    {
        var baseType = method.DeclaringType.GetGenericTypeDefinition().MakeGenericType(DeclaringTypeArguments);
        return MethodInfo.GetMethodFromHandle(method.MethodHandle, baseType.TypeHandle) as MethodInfo;
    }
    public static void Main(String[] args)
    {
        List<Type> list = new List<Type>();
        Action<Type> action  = list.Add;
        Console.WriteLine(action.Method.Convert(typeof(string)));
        Console.Read();
    }

你必须重新思考,因为方法是不同的。虽然hasValue的唯一区别是MethodInfo.DeclaringType,但Value属性中的区别是MethodInfo.ReturnType。