2010-09-24 8 views
7

Wyobraź typ tak (C#):Jak uzyskać ogólną metodę zamkniętego rodzaju generycznego, mając otwartą metodę MethodInfo z otwartego typu ogólnego?

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

Biorąc mam otwarte generycznego MethodInfo z otwartym generycznej wersji typu (IAmGeneric<>.SoAmI<>()) i następującej tablicy

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

szukam dobrze wykonanie i niezawodny sposób uzyskania zamkniętej wersji MethodInfo w następujący sposób:

IAmGeneric<int>.SoAmI<string>() 

UPDATE:

przez niezawodny Znaczy powinien obsługiwać przypadki, gdy metoda nie jest publiczna, ma kilkanaście przeciążeń, wykorzystuje rodzajowe argumentów typu bazowego, a nie tylko jego bezpośredni interfejs itd

+0

Jeśli masz już 'MethodInfo' z interfejsu, dlaczego dbają o przeciążeniach i ogólnych argumentów typu bazowego? Rozwiązanie z @DarrenKopp to wszystko, czego potrzebujesz. –

Odpowiedz

1

coś takiego tak? Nie jestem pewien dokładnie to, czego szukasz, może rozwinąć swoje pytanie ... To na pewno potrzebujesz kontrole dodanej (jak sprawdzenie, czy deklarując typ jest rodzajowy/jeśli metoda jest nazwą rodzajową, 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

Oto sprawa, która jest dość skomplikowane, aby uzyskać prawo:

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

dla mnie rozwiązaniem jest użycie GetMethods(...).Select() i porównać nazwę metody, liczby parametrów, typy i parametry typu liczyć na znalezienie właściwej metody (w zasadzie wszystko, co jest częścią podpis metody).

+0

yeap, to może zadziałać, i właśnie to robię teraz. Jednak występ nie jest gwiezdny, dlatego pytam, czy jest lepszy sposób –

0

Zastosowanie MethodBase.GetMethodFromHandle, jak wskazano w 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()); 
Powiązane problemy