105 votes

C # utilise System.Type comme paramètre générique

J'ai une liste de types (System.Type) qui doivent être interrogés sur la base de données.

Pour chacun de ces types, je dois appeler la méthode d'extension suivante (qui fait partie de LinqToNhibernate):

 Session.Linq<MyType>()
 

Cependant, je n'ai pas MyType, mais je veux utiliser un type à la place.

Ce que j'ai c'est:

 System.Type typeOne;
 

Mais je ne peux pas effectuer les tâches suivantes:

 Session.Linq<typeOne>()
 

Comment utiliser un type en tant que paramètre générique?

109voto

Jon Skeet Points 692016

Vous ne pouvez pas, directement. Le point de génériques est de fournir au moment de la compilation de sécurité de type, où vous savez le type qui vous intéresse au moment de la compilation, et peut travailler avec les instances de ce type. Dans votre cas, vous ne connaissez que le Type de sorte que vous ne pouvez pas obtenir à tout moment de la compilation vérifie que tous les objets sont des instances de ce type.

Vous devez appeler la méthode par réflexion - quelque chose comme cela:

// Get the generic type definition
MethodInfo method = typeof(Session).GetMethod("Linq", 
                                BindingFlags.Public | BindingFlags.Static);

// Build a method with the specific type argument you're interested in
method = method.MakeGenericMethod(typeOne);
// The "null" is because it's a static method
method.Invoke(null, arguments);

Si vous avez besoin d'utiliser ce type de beaucoup, vous trouverez peut-être plus pratique d'écrire votre propre méthode générique qui appelle toutes les autres méthodes génériques dont il a besoin, et ensuite appeler votre méthode avec la réflexion.

36voto

Marc Gravell Points 482669

Pour ce faire, vous devez utiliser la réflexion:

 typeof(Session).GetMethod("Linq").MakeGenericMethod(typeOne).Invoke(null, null);
 

(en supposant que Linq<T>() est une méthode statique sur le type Session )

Si Session est en réalité un objet , vous devez savoir où la méthode Linq est réellement déclarée et passer dans Session comme argument:

 typeof(DeclaringType).GetMethod("Linq").MakeGenericMethod(typeOne)
     .Invoke(null, new object[] {Session});
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X