Est-ce que quelqu'un pourrait me fournir des exemples simples en C# de covariance, contravariance, invariance et contrainvariance (si cela existe).
Je n'ai aucune idée de ce que "contrainvariance" signifie. Le reste est facile.
Voici un exemple de covariance:
void NourrirLesAnimaux(IEnumerable animaux)
{
foreach(Animal animal in animaux)
animal.Nourrir();
}
...
List girafes = ...;
NourrirLesAnimaux(girafes);
L'interface IEnumerable
est covariante. Le fait que Girafe est convertible en Animal implique que IEnumerable
est convertible en IEnumerable
. Comme List
implémente IEnumerable
, ce code fonctionne en C# 4; il aurait échoué en C# 3 car la covariance sur IEnumerable
ne fonctionnait pas en C# 3.
Cela devrait avoir du sens. Une séquence de girafes peut être traitée comme une séquence d'animaux.
Voici un exemple de contravariance:
void FaireQuelqueChoseAUneGrenouille(Action action, Grenouille grenouille)
{
action(grenouille);
}
...
Action nourrir = animal=>{animal.Nourrir();}
FaireQuelqueChoseAUneGrenouille(nourrir, new Grenouille());
Le délégué Action
est contravariant. Le fait que Grenouille est convertible en Animal implique que Action
est convertible en Action
. Remarquez comment cette relation est en sens inverse de la covariante; c'est pourquoi c'est "contra" variant. En raison de la convertibilité, ce code fonctionne; il aurait échoué en C# 3.
Cela devrait avoir du sens. L'action peut prendre n'importe quel Animal; nous avons besoin d'une action qui peut prendre n'importe quel Grenouille, et une action qui peut prendre n'importe quel Animal peut sûrement aussi prendre n'importe quel Grenouille.
Un exemple d'invariance:
void LireEtEcrire(IList mammiferes)
{
Mammifere mammifere = mammiferes[0];
mammiferes[0] = new Tigre();
}
Pouvons-nous passer une IList
à cette fonction? Non, car quelqu'un va écrire un Tigre dedans, et un Tigre ne peut pas être dans une liste de girafes. Pouvons-nous passer une IList
à cette fonction? Non, car nous allons lire un Mammifère à partir de celle-ci, et une liste d'Animaux peut contenir une Grenouille. IList
est invariante. Il ne peut être utilisé que tel qu'il est réellement.
Pour quelques réflexions supplémentaires sur la conception de cette fonctionnalité, consultez ma série d'articles sur comment nous l'avons conçue et construite.
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
0 votes
Quelqu'un a donné la distribution d'un objet à
System.Object
comme exemple de covariance? C'est complètement faux.0 votes
J'ai interprété cela comme le passage d'un genre d'objet (avec un type plus spécifique, plus dérivé) à la place de
System.Object
, et non pas nécessairement la conversion deobject
enSystem.Object
, ce qui serait inutile.0 votes
Variance ne doit pas être confondu avec casting, ils ne sont pas la même chose. Voir: Différence entre covariance et upcasting.