44 votes

C #: Variance (Covariance / Contravariance) est-il un autre mot pour Polymorphism?

J'essaie de comprendre le sens exact des mots Covariance et Contravariance partir de plusieurs articles en ligne et de questions sur StackOverflow, et d'après ce que je peux comprendre, ce n'est qu'un autre mot pour le polymorphisme .

Suis-je correct avec la déclaration ci-dessus? Ou est-ce que je me suis trompé?

70voto

Jon Skeet Points 692016

C'est certainement lié au polymorphisme. Je ne dirais pas qu'ils sont juste "un mot" pour le polymorphisme si elles sont sur des situations très spécifiques, où vous pouvez traiter un type comme si c'était un type dans un certain contexte.

Par exemple, avec un polymorphisme vous pouvez traiter de toute référence à un Banana comme une référence à un Fruit - mais cela ne signifie pas que vous pouvez substituer Fruit chaque fois que vous voyez le type Banana. Par exemple, un List<Banana> ne peut pas être traité comme un List<Fruit> car list.Add(new Apple()) est valable pour List<Fruit> mais pas pour List<Banana>.

La Covariance permet un plus "grand" (moins précis) type à être substitué à un API, où le type d'origine est seulement utilisé dans une "sortie" de la position (par exemple, une valeur de retour). La Contravariance permet un "petit" (plus spécifique) type à être substitué à un API, où le type d'origine est seulement utilisé dans une "entrée" de position.

Il est difficile de rentrer dans tous les détails dans une seule SORTE de post (bien que j'espère que quelqu'un d'autre va faire un meilleur travail que cela!). Eric Lippert a une excellente série de billets de blog à ce sujet.

49voto

Eric Lippert Points 300275

Merci à tous pour le shout-outs, les gars.

Jon et Rasmus réponses sont beaux, je voudrais juste ajouter une rapide note technique.

Lorsque l'on parle de façon décontractée et informelle, oui, les gens utilisent "covariance" et "la contravariance" pour désigner un type spécifique de polymorphisme. C'est le type de polymorphisme où vous traiter une séquence d'araignées comme s'il s'agissait d'une séquence d'animaux.

Étions-nous pour obtenir tous les ordinateur-sciency et essayer de faire plus de la définition technique, alors je n'aurais probablement pas dire que la covariance et la contravariance sont "une sorte de polymorphisme". Je l'approche plus technique de définition comme ceci:

Tout d'abord, je voudrais noter qu'il existe deux types de polymorphisme en C# que vous pourriez être en train de parler, et il est important de ne pas les confondre.

Le premier type est appelé traditionnellement "ad hoc polymorphisme", et c'est le polymorphisme où vous avez une méthode M(Animal x), et vous passez des araignées et des girafes et des wallabies, et la méthode uniformément traite ses passée en arguments de la même façon en utilisant les points communs garanti par l'Animal de la classe de base.

Le deuxième type est appelé traditionnellement "polymorphisme paramétrique", ou "générique polymorphisme". C'est la capacité de faire une méthode générique M<T>(T t) et ensuite avoir un tas de code dans la méthode de nouveau, traite l'argument de manière uniforme basé sur les points communs garanti par les contraintes sur les T.

Je pense que vous parlez du premier type de polymorphisme. Mais mon point est simplement que nous pouvons définir polymorphisme comme la capacité d'un langage de programmation pour traiter les différentes choses de manière uniforme basé sur une communauté. (Par exemple, un type de base, ou connu de mise en œuvre de l'interface.)

La Covariance et la contravariance est la capacité d'un langage de programmation pour profiter de points communs entre les types génériques en déduit connu les points communs de leurs arguments de type.

21voto

Rasmus Faber Points 24195

Vous pouvez penser au sujet de la covariance et la contravariance comme étant une forme avancée de polymorphisme. Non seulement vous pouvez utiliser un enfant de la classe, comme si c'était son parent de la classe, avec la covariance et la contravariance, le polymorphisme s'étend aux classes qui se rapporte à la polymorphes classes.

Imaginez deux classes:

public class Pet { /*...*/ }
public class Cat:Pet { /*...*/ }

Le polymorphisme est la capacité de pouvoir utiliser un Cat comme Pet:

void Feed(Pet pet) { /* ... */ }

Cat cat = ...
Feed(cat);

La covariance et la contravariance est utilisé pour parler du fait d'être en mesure d'utiliser un ICollection<Cat> comme ICollection<Pet> (covariance):

void FeedAll(ICollection<Pet> pets) { /* ... */ }

List<Cat> cats = ...
FeedAll(cats);

ou utiliser un Action<Pet> comme Action<Cat> (contravariance):

Action<Pet> GetFeeder() { /* ... */ }

Action<Cat> feeder = GetFeeder();

Eric Lippert a écrit une grande série de blog à ce sujet quand ils ont d'abord la conception de la fonctionnalité. La première partie est ici.

13voto

-2voto

Sali Hoo Points 138

Je pense que c'est un type spécial de polymorphisme pas un autre mot pour cela. C'est un polymorphisme chez les délégués, un délégué avec un type de base de retour pouvant accepter un type enfant.

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