Come chiamare un metodo generico con un determinato object Type?

Voglio chiamare il mio metodo generico con un determinato object tipo.

void Foo(Type t) { MyGenericMethod(); } 

ovviamente non funziona

Come posso farlo funzionare?

Il tuo esempio di codice non funzionerà, perché il metodo generico prevede un identificatore di tipo, non un’istanza della class Type. Dovrai usare la riflessione per farlo:

 public class Example { public void CallingTest() { MethodInfo method = typeof (Example).GetMethod("Test"); MethodInfo genericMethod = method.MakeGenericMethod(typeof (string)); genericMethod.Invoke(this, null); } public void Test() { Console.WriteLine(typeof (T).Name); } } 

Tieni presente che questo è molto fragile, preferirei piuttosto cercare un altro schema per chiamare il tuo metodo.

Un’altra soluzione hacky (forse qualcuno può renderla un po ‘più pulita) sarebbe usare un po’ di magia per le espressioni:

 public class Example { public void CallingTest() { MethodInfo method = GetMethod(x => x.Test()); MethodInfo genericMethod = method.MakeGenericMethod(typeof (string)); genericMethod.Invoke(this, null); } public static MethodInfo GetMethod(Expression> expr) { return ((MethodCallExpression) expr.Body) .Method .GetGenericMethodDefinition(); } public void Test() { Console.WriteLine(typeof (T).Name); } } 

Si noti il ​​passaggio dell’identificatore di tipo “object” come argomento di tipo generico nel lambda. Non riuscivo a capire così in fretta come girarlo. In ogni caso, penso che sia sicuro per la compilazione. In qualche modo sembra sbagliato: /

È necessario usare la riflessione, sfortunatamente (per i motivi menzionati da Jared). Per esempio:

 MethodInfo method = typeof(Foo).GetMethod("MyGenericMethod"); method = method.MakeGenericMethod(t); method.Invoke(this, new object[0]); 

Ovviamente vorresti più controllo degli errori nella realtà 🙂


Nota a margine: il mio MSDN locale non specifica che il parametro da MakeGenericMethod è un array di parametri, quindi mi sarei aspettato di richiedere:

 method = method.MakeGenericMethod(new Type[] { t }); 

ma sembra che sia un array di parametri in realtà e i documenti MSDN online sono d’accordo. Dispari.

Questo approccio non funzionerà. Il motivo per cui quel tipo è un object il cui tipo è determinato in fase di runtime. Comunque stai provando ad usarlo per chiamare un metodo generico. Un tipo di chiamata di metodo generico viene stabilito in fase di compilazione. Quindi un object Type non può mai essere usato per un parametro type su un metodo generico.