Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

reflection

Let's say that I have the methodInfo for something like Nullable<int>.HasValue. Is there anyway to convert it to Nullable<string>.HasValue?

I know for a regular generic method I can do methodInfo.GetGenericMethod() but I don't see a way to do it for the type from the method, without doing more reflection overhead. If I already have the method why do I have to reflect again?

Interestingly enough the methods all have the same MetadataToken, which makes it more impressive that somehow Module.ResolveMember seems to pull the right one out.

Is there any way to do this with the Module.ResolveMethod? Essentially, the method and type may both have generic parameters, and I may need to switch them. Since the MethodInfo always says its token is the same and the token represents the MethodInfo is the most open version of the method. I just need someway for it to be converted to my type.

Edit: More digging, it appears that for something like List<T>.Add, List<int>.Add metadata token from which i retrieve is actually living in my module, while the generic definition lives in a different module.

I really don't want to do reflection once I retrieve the member once, as it's very difficult to resolve the exact same method being invoked.

Okay maybe I'm just stupid, but why exactly does this not work::

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

Why does methodInfo2 say that it is Add(T) rather than Add(string)?

like image 979
Michael B Avatar asked Nov 05 '10 01:11

Michael B


1 Answers

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

like image 179
Samuel Neff Avatar answered Nov 16 '22 01:11

Samuel Neff