Question

Quelqu'un peut-il expliquer pourquoi il est nécessaire d'ajouter un paramètre out ou in pour indiquer qu'un type générique est une variante Co ou Contra en C # 4.0?

J'essaie de comprendre pourquoi c'est important et pourquoi le compilateur ne peut pas le comprendre ..

Merci,

Josh

Était-ce utile?

La solution

Eric Lippert, qui travaille sur le langage, a publié une série de messages sur msdn qui devraient aider à clarifier les problèmes en jeu:
http://blogs.msdn.com/ericlippert/ archive / tags / Covariance + et + Contravariance / default.aspx

Lorsque vous lisez les articles affichés sur ce lien, commencez par le bas et avancez.

Vous finirez par accéder à # 7 (Pourquoi avons-nous besoin d'une syntaxe?) .

Autres conseils

En fait, nous n'en avons pas besoin , nous n'avons plus besoin de abstract sur les classes, ni à la fois out et ref. Ils existent uniquement pour que nous, les programmeurs, puissions clarifier notre intention, pour que le programmeur de maintenance sache ce que nous faisons, et que le compilateur puisse vérifier que nous le faisons bien.

Le problème principal est que si vous avez une hiérarchie de classe comme:

   class Foo { .. } 

   class Bar : Foo { .. } 

Et vous avez un IEnumerator<Bar>, vous ne pouvez pas l'utiliser comme IEnumerator<Foo> même si cela serait parfaitement sûr. En 3.5, cela force un grand nombre de gyrations douloureuses. Cette opération serait toujours sûre mais est refusée par le système de types car elle ne connaît pas l'utilisation covariante du paramètre de type générique. Bar ne peut que renvoyer un Foo et chaque IEqualityComparer<Foo> est un IEqualityComparer<Bar>.

De même, si vous aviez un <=>, il peut être utilisé pour comparer toute paire d'objets de type <=>, même si l'un ou les deux est un <=>, mais il ne peut pas être converti dans un <=> car il ne sait pas sur l'utilisation contravariante du paramètre de type générique. <=> ne consomme que des objets de type <=> et chaque <=> est un <=>.

Sans ces mots clés, nous sommes obligés de supposer que l'argument générique peut apparaître à la fois comme argument d'une méthode et comme type de résultat d'une méthode. Par conséquent, nous ne pouvons autoriser en toute sécurité aucune des conversions ci-dessus.

Grâce à eux, le système de types est libre, ce qui nous permet d’effectuer une conversion ascendante et descendante en toute sécurité entre les interfaces dans la direction indiquée par le mot clé. Nous obtenons des erreurs indiquant dans quels cas nous enfreindrions les mesures disciplinaires requises pour assurer cette sécurité.

Les mots clés in et out sont des mots clés depuis C # 1.0 et ont été utilisés dans le contexte des paramètres <=> - et <=> - des méthodes.

La covariance et la contravariance sont des contraintes sur la manière de mettre en œuvre une interface. Il n'y a pas de bon moyen de les déduire - le seul moyen, je pense, est d'utiliser, et ce serait compliqué et à la fin cela ne fonctionnerait pas.

Jon et Joel ont tous deux fourni une réponse assez complète à cette question, mais le fait est qu'ils ne sont pas nécessaires par le compilateur, mais contribuent plutôt à garantir la sécurité de la mise en œuvre en indiquant explicitement la variance du paramètre. Cela suit un schéma très similaire à celui qui impose le out ou ref mot clé sur le site appelant et sur le site de déclaration.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top