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

前端 未结 4 1446
醉酒成梦
醉酒成梦 2020-12-06 12:26

Let\'s say that I have the methodInfo for something like Nullable.HasValue. Is there anyway to convert it to Nullable.HasValue

相关标签:
4条回答
  • 2020-12-06 12:50

    Solved it. But the big question is this a safe way to do it? Is there something I could be doing wrong here?

        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();
        }
    
    0 讨论(0)
  • 2020-12-06 12:54

    You can do it in one line with MethodBase.GetMethodFromHandle but in order to use this method you'll have to pass typeof(List<string>) not just typeof(string).

    var methodinfo = typeof(List<int>).GetMethod("Add");
    var methodinfo2 = MethodBase.GetMethodFromHandle(methodinfo.MethodHandle,
                                                     typeof (List<string>).TypeHandle);
    
    Console.WriteLine(methodinfo);
    Console.WriteLine(methodinfo2);
    

    This link includes the above sample and an exlpanation of why ResolveMethod doesn't work.

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

    0 讨论(0)
  • 2020-12-06 12:57

    You can do it easily with a little more reflection. You can't do it magically without reflection.

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

    Of course this is pretty specific to only work for generic types with a single type parameter but it could be generalized to do more if needed.

    0 讨论(0)
  • 2020-12-06 13:07

    You have to reflect again because the methods are different. While the only difference for HasValue is the MethodInfo.DeclaringType, the difference in the Value property is the MethodInfo.ReturnType.

    0 讨论(0)
提交回复
热议问题