2010-09-24 15 views
7

Imagínese tipo como éste (C#):¿Cómo obtener el método genérico en el tipo genérico cerrado, teniendo MethodInfo abierto del tipo genérico abierto?

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

Dado que tengo abierta genérica MethodInfo de la versión genérica abierta del tipo (IAmGeneric<>.SoAmI<>()) y la siguiente matriz

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

Busco bien realizar y fiable manera de conseguir la versión cerrada de la MethodInfo así:

IAmGeneric<int>.SoAmI<string>() 

ACTUALIZACIÓN:

por fiable quiero decir que debe manejar los casos en que el método no es pública, tiene docenas de sobrecargas, utiliza argumentos genéricos de tipo base, no sólo su interfaz inmediata etc.

+0

Si ya tiene un 'MethodInfo' desde la interfaz, ¿por qué te preocupas por las sobrecargas y los argumentos genéricos de tipo base? La solución de @DarrenKopp es todo lo que necesitas. –

Respuesta

1

Algo parecido a lo que? No estoy seguro exactamente lo que está buscando, tal vez ampliar su pregunta ... Esto definitivamente necesitaría algunas comprobaciones adicionales (como la comprobación de si el tipo de declarar es genérico/si el método es genérico, 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

Aquí es una caso que es bastante complejo para hacerlo bien:

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

para mí, la solución es utilizar GetMethods(...).Select() y compara el nombre del método, el recuento de parámetros, tipos y parámetros de tipo de contar hasta encontrar el método adecuado (básicamente todo lo que forma parte de la firma del método).

+0

yeap, eso podría funcionar, y eso es lo que estoy haciendo en este momento. Sin embargo, el rendimiento está lejos de ser estelar, por lo tanto, estoy preguntando si hay una mejor manera –

0

Uso MethodBase.GetMethodFromHandle, como se señala en 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()); 
Cuestiones relacionadas