Appel d’une méthode générique avec un type dynamic

Disons que j’ai les classes suivantes

public class Animal { .... } public class Duck : Animal { ... } public class Cow : Animal { ... } public class Creator { public List CreateAnimals(int numAnimals) { Type type = typeof(T); List returnList = new List(); //Use reflection to populate list and return } } 

Maintenant, dans un code plus tard, je veux lire dans quel animal créer.

 Creator creator = new Creator(); ssortingng animalType = //read from a file what animal (duck, cow) to create Type type = Type.GetType(animalType); List animals = creator.CreateAnimals(5); 

Maintenant, le problème est que la dernière ligne n’est pas valide. Y a-t-il une manière élégante de faire cela alors?

Je ne connais pas l’élégance, mais la façon de le faire est:

 typeof(Creator) .GetMethod("CreateAnimals") .MakeGenericMethod(type) .Invoke(creator, new object[] { 5 }); 

Pas vraiment. Vous devez utiliser la reflection, en gros. Les génériques visent en réalité le typage statique plutôt que les types connus uniquement au moment de l’exécution.

Pour utiliser la reflection, vous devez utiliser Type.GetMethod pour obtenir la définition de la méthode, puis appeler MethodInfo.MakeGenericMethod(type) , puis l’appeler comme toute autre méthode.

Essaye ça:

 public List CreateAnimals(int numAnimals) where T : Animal { Type type = typeof(T); List returnList = new List(); //Use reflection to populate list and return } 

Il devrait s’assurer que les types autorisés pour CreateAnimals héritent de Animal. Avec un peu de List animals = creator.CreateAnimals(5); , cela n’aura pas de problème avec List animals = creator.CreateAnimals(5);

Les clés sont MakeGenericType () et MakeGenericMethod (). Une fois que vous êtes devenu dynamic avec les types, vous ne pouvez pas vraiment revenir à la saisie statique. Ce que vous POUVEZ faire est de créer la liste dynamicment, en utilisant Activator.CreateInstance(typeof(List<>).MakeGenericType(type)) , puis en appelant dynamicment la méthode générique en utilisant des méthodes de reflection similaires.

 List animals = creator.CreateAnimals(5); 

Dans la ligne ci-dessus de votre exemple, animalType et type sont des variables d’exécution, pas des types, ce qui est bien sûr un non-sens. Une version générique n’a de sens que si vous connaissez les types au moment de la compilation, par exemple:

 List animals = creator.CreateAnimals(5); 

où vous devriez contraindre les types en conséquence. Si les types ne sont pas connus, vous devez compter entièrement sur la reflection …