11
votes

Quels sont les types de covariance en C #? (Ou, covariance: par exemple)

Covariance est (à peu près) la capacité de héritage miroir de types "simples" dans des types complexes qui les utilisent.
Par exemple. Nous pouvons toujours traiter une instance de chat comme une instance de animal . Un ComplexType peut être traité comme un ComplexTyPe , si complextype est covariant.

Je me demande: quels sont les "types" de la covariance et comment se rapportent-ils à C # (sont-ils soutenus?)
Les exemples de code seraient utiles.

Par exemple, un type est type de retour Covariant , pris en charge par Java, mais pas C #.

J'espère que quelqu'un avec des côtelettes de programmation fonctionnelle peut faire carrer, aussi!


11 commentaires

Je pense que vous confondez deux concepts différents (mais similaires). On s'appelle la covariance et l'autre s'appelle Contravariance.


Si vous recherchez des exemples - presque tous les collections de standard .NET sont covariants.


@Nik correction. Presque toutes les interfaces .NET dans le System.Generic.Collections Espace de noms sont Covariant.


@Aron oui, c'est ce que je voulais dire, merci


Il y a un bel article MSDN sur la covariance d'une contrevenance. ici vous allez.


@Aron Soins pour développer cela? Ma compréhension est que: 1. Covariance traduit Héritage à des types complexes ( Cat ienumerable ), et 2. Contravariance inverse la Héritage ( Cat action **> ** action ). Et je demande seulement covariance ici.


Je discute Covariant et Contravariance en Java Un peu, c'est probablement une forme différente c # cependant.


Vous voudrez peut-être lire la longue série d'articles que j'ai écrites tout en concevant les caractéristiques de la covariance / de Contravariance ajoutées au C # 4. Celles-ci sont en ordre de la plus récente au moins récente, alors commencez en bas. blogs.msdn.com/b/ericlippert/ Archives / Tags / ...


@ERICLIPPERT WOW, c'est une longue liste! J'ai lu certains de ces articles. Je vais y aller et mettre à jour ma réponse ci-dessous avec les nouvelles découvertes :)


Dupliqué possible de Covariance et Contravariance Exemple de monde réel


@CristidiaconesCu Je rétracte ma déclaration, vous comprenez la covariance et la Contravarariance.


3 Réponses :


10
votes

Voici ce que je peux penser:

Mise à jour forte> p>

Après avoir lu les commentaires constructifs et la tonne d'articles pointés (et écrits) par Eric Lippert, j'ai amélioré le Réponse: p>

  • Mise à jour de la cassée du tableau Covariant Li>
  • Ajout de la variance de déléguée "pure" li>
  • Ajout d'autres exemples de la BCL LI>
  • a ajouté des liens vers des articles qui expliquent les concepts en profondeur. LI>
  • a ajouté une nouvelle section sur la fonction de fonction supérieure de la fonction Covariance. Li> ul>

    Type de retour COVARANCE FORT>: P>

    Disponible en Java (> = 5) [1] code> sup> et c ++ [2] code> sup>, non pris en charge dans C # (Eric Lippert explique Pourquoi pas et Ce que vous pouvez faire à ce sujet ): p> xxx pré>

    covariance d'interface strong> [3] code> sup> - pris en charge C # p>

    Le BCL définit l'interface générique iEnumerable code> CoVariant: p> xxx pré>

    Ainsi, l'exemple suivant est valide: p> xxx pré>

    Notez qu'un ienumerable code> est par définition "lecture seule" - vous c Je n'ai pas d'ajouter des éléments.
    Contrairement à la définition de ilist code> qui peut être modifié par exemple. en utilisant .add () code>: p> xxx pré>

    Délégué covariance strong> au moyen de groupes de méthodes [4] code> sup> - supporté en C # P>

    A < B => ... => Trainer<A> < Trainer<B> 
    


2 commentaires

Juste une note sur la cassette Covariance: Si vous ajoutez une troisième ligne de objarray [1] = nouvel objet (); , tandis que legal à la compilation lancera des exceptions au moment de l'exécution. En ce sens, contrairement aux autres exemples, Tarra Covariance est cassé


Bonne liste. Un petit changement que je ferais est de noter qu'il existe deux types de covariance déléguée à partir de C # 4. Le type que vous parlez d'appeler que j'appelle habituellement Méthode GROUP COVARANCE . Délégué covariance permet délégué r d (); ... D dB = () => nouvelle banane (); D df = dB;



1
votes

Java utilise le concept de la variance du site pour les types génériques: la variance nécessaire est spécifiée sur chaque site d'utilisation. C'est pourquoi les programmeurs Java sont tenus de familiariser avec la règle soi-disant PECS. Oui, c'est difficile à manier et a déjà reçu beaucoup de critiques.


2 commentaires

+1 intéressant. Ceci Cette question et le lien article donne une description de la différence entre la variance de site d'utilisation (Java) et la variance du site de déclaration (C #).


Merci pour le lien, Cristi, c'est l'une des meilleures réponses dans l'ensemble!



3
votes

Ceci est mieux expliqué en termes de types de structure plus génériques. Considérer:

  1. TUPLE TYPES: (T1, T2), une paire de types T1 et T2 (ou plus généralement N-tuples); Li>
  2. Types de fonction: T1 -> T2, une fonction avec l'argument Type T1 et Résultat T2; Li>
  3. Types mutables: Mut (t), une variable mutable tenant un t. li> ol>

    Les tuples sont covariants dans leurs deux types de composants, c'est-à-dire (T1, T2)

    Les fonctions sont covariantes dans leur résultat et contravaret dans leur argument, c'est-à-dire (T1 -> T2) U2) IFF U1

    Types mutables sont invariants, c'est-à-dire mut (t)

    toutes ces règles sont les règles de sous-typage les plus générales correctes. p>

    maintenant, un objet ou une interface Tapez comme vous le savez des langues traditionnelles peut être interprété comme une forme de tuple fantaisie contenant ses méthodes comme des fonctions, entre autres. Par exemple, l'interface p> xxx pré>

    représente essentiellement le type p> xxx pré>

    où f, g et x correspondent au 1er , 2e et 3ème composante du tuple, respectivement. P>

    Il découle des règles ci-dessus que c (t, u, v)

    Un autre exemple: p> xxx pré>

    est p> xxx pré>

    ici, d (t)

    Il existe également un quatrième cas, parfois appelé "Bivariance", ce qui signifie à la fois co et contrevenart en même temps. Par exemple, P>

    interface E<T> { Int f(Int) }
    


0 commentaires