How to get a generic method on a private generic type by opening MethodInfo from an open generic type?

Imagine this type (C #):

public interface IAmGeneric<T> { void SoAmI<T1>(T one, T1 two); } 

Given that I have an open generic MethodInfo from an open generic version of a type ( IAmGeneric<>.SoAmI<>() ) and the following array

 new[] { typeof(int), typeof(string) }' 

I am looking for an efficient and reliable way to get a private version of MethodInfo as follows:

 IAmGeneric<int>.SoAmI<string>() 

UPDATE:

reliable, I mean that it should handle cases where the method is not public, has a dozen overloads, uses common arguments from the base type, and not just its direct interface, etc.

+7
generics reflection c #
source share
3 answers

Something like that? Not sure what exactly you are looking for, perhaps expanding your question ... This will definitely require additional checks (for example, checking whether the type of an ad is general or if a general method, etc.)

 var method = typeof(IAmGeneric<>).GetMethod("SoAmI"); var types = new[] { typeof(int), typeof(string) }; var methodTypeParams = method.GetGenericArguments(); var fullType = method.DeclaringType.MakeGenericType(types.Take(types.Length - methodTypeParams.Length).ToArray()); var fullMethod = fullType.GetMethod(method.Name).MakeGenericMethod(types.Skip(types.Length - methodTypeParams.Length).ToArray()); 
+1
source share

Here is a case that is pretty hard to get right:

 public interface IAmGeneric<T> { void SoAmI<T1, T2>(T one, T1 two, T2 three); void SoAmI<T1, T2>(T one, T2 two, T1 three); void SoAmI<T1, T2>(T1 one, T two, T2 three); void SoAmI<T1, T2>(T2 one, T1 two, T three); void SoAmI<T1, T2, T3>(T2 one, T1 two, T3 three); } 

For me, the solution is to use GetMethods(...).Select() and compare the method name, number of parameters, types and type parameters to find the correct method (basically everything that is part of the method signature).

+1
source share

Use MethodBase.GetMethodFromHandle as indicated in this related answer :

 var ty = typeof(IAmGeneric<>); var numTyParams = ty.GenericTypeArguments.Length; var mi = ... do something with ty to get generic def for SoAmI<> ... var parameters = new[] { typeof(int), typeof(string) }; var output = MethodBase.GetMethodFromHandle(mi.MethodHandle, ty.MakeGenericType(parameters.Take(numTyParams).ToArray()).TypeHandle).MakeGenericMethod(parameters.Skip(numTyParams).ToArray()); 
0
source share

All Articles