9
votes

Aidez-moi à comprendre le polymorphisme lorsque vous utilisez des génériques en C #

J'ai un problème à comprendre comment le polymorphisme fonctionne lors de l'utilisation de génériques. À titre d'exemple, j'ai défini le programme suivant:

MyClass newClass = new MyClass();
IMyInterface myInterface = (IMyInterface)newClass;


4 commentaires

C'est là que les gens trotent des mots effrayants comme la covariance et la contrevenance.


@Greg: sur le côté de plus, je me sens comme mon posséder la compréhension de ces concepts a vraiment été enveloppée récemment en raison de la pléthore de questions telles que celles-ci.


Les concepts sont bons, mais les noms sont effrayants. :)


@Greg: convenu. Je propose que nous les changeons à Gobbling and Spewing .


3 Réponses :


4
votes

Remarque: Dans tous les cas, vous devrez initialiser le champ code> code> sur un objet concret implémentant ilist > code>

lorsque vous gardez la contrainte générique , vous pouvez faire: p> xxx pré>

Lorsque vous ne le faites pas, vous pouvez faire: p>

MyContainer container = new MyContainer();
container.Contents.Add(new MyClass());
this.CallAllMethodsInContainer(container);


0 commentaires

1
votes

C'est un problème de covariance

http://msdn.microsoft.com/en-us/library /dd799517.aspx

Vous ne pouvez pas lancer myContainer à myContainer parce que vous pouviez faire des choses comme Sommaire.Ajouter (nouveau autreClassThatimplemplementsImyInterface ())


0 commentaires

3
votes

WOW, cette question a été lancée beaucoup récemment.

Réponse courte: Non, ce n'est pas possible. Voici ce que est possible: xxx

et voici pourquoi ce que vous avez essayé n'est pas possible (pris de cette réponse récente de la mine ):

Considérez la liste type. Dites que vous avez une liste list et une liste . String dérive de l'objet, mais il ne veut pas que list dérive de list ; Si tel est le cas, vous pouvez avoir du code comme celui-ci: xxx

Le code ci-dessus illustre ce que signifie être (et ne pas être) a Type Covariant . Notez que la diffusion d'un type t à un autre type t d dérive de b est possible (en .NET 4.0) si t est covariant ; Un type générique est covariant si son argument de type générique n'apparaît jamais sous la forme de la sortie - c'est-à-dire des propriétés en lecture seule et des valeurs de retour de fonction.

pense de cette façon: si un type T toujours fournit un B , puis une qui fournit toujours un d ( t < / code>) sera en mesure de fonctionner comme un t car tous les d s sont b s.

Incidemment, un type est Contravariant si son paramètre de type générique apparaît uniquement sous la forme d'entrée - c'est-à-dire des paramètres de la méthode. Si un type t est contravariant alors il peut être coulé à un t , aussi étrange que cela peut sembler.

pense de cette façon: Si un type t Toujours nécessite un B , alors il peut entrer pour une personne qui nécessite toujours un < code> d car, à nouveau, tous d s sont b s.

Votre myContainer classe est Ni covariant ni contrevraveurt, car son paramètre de type apparaît dans les deux contextes - comme entrée (via contenu.add ) et comme sortie (via le contenu


0 commentaires