Question

Je n’ai pas assisté à PDC 2008, mais j’ai entendu dire que la version 4.0 de C # était annoncée pour prendre en charge la covariance et la contre-variance génériques. Autrement dit, List < string > peut être affecté à List < objet > . Comment cela pourrait-il être?

Dans le livre de Jon Skeet C # en profondeur , il est expliqué pourquoi les génériques C # ne prennent pas en charge la covariance et la contra-variance. C'est principalement pour écrire du code sécurisé. Maintenant, C # 4.0 a changé pour les supporter. Cela apporterait-il du chaos?

Quelqu'un sait-il que les détails de C # 4.0 peuvent donner des explications?

Était-ce utile?

La solution

La variance ne sera prise en charge que de manière sûre - en fait, en utilisant les capacités que possède déjà le CLR. Ainsi, les exemples que je cite dans le livre voulant que vous utilisiez une liste comme liste ; Fruit (ou quoi que ce soit d'autre) ne fonctionneraient toujours pas - mais quelques autres scénarios seront.

Tout d'abord, il ne sera pris en charge que pour les interfaces et les délégués.

Deuxièmement, il demande à l'auteur de l'interface / délégué de décorer les paramètres de type comme dans (pour contravariance) ou out (pour covariance). L'exemple le plus évident est IEnumerable < T > , qui ne vous permet que de prendre des valeurs & out; " il ne vous permet pas d’en ajouter de nouveaux. Cela deviendra IEnumerable < out T > . Cela ne nuit en rien à la sécurité de type, mais vous permet de renvoyer un IEnumerable < chaîne > à partir d'une méthode déclarée comme retournant IEnumerable < objet > .

La contravariance est plus difficile à donner des exemples concrets d’utilisation d’interfaces, mais c’est facile avec un délégué. Considérez Action < T > - qui représente simplement une méthode prenant un paramètre T . Il serait bien de pouvoir convertir de manière transparente en utilisant une Action < objet > en tant que Action < chaîne > - toute méthode prenant un objet . Le paramètre va bien s’il est présenté avec une chaîne . Bien sûr, C 2 a déjà une certaine covariance et une contravariance des délégués, mais via une conversion réelle d’un type de délégué à un autre (création d’une nouvelle instance) - voir P141-144 pour des exemples. C # 4 rendra cela plus générique, et (je crois) évitera de créer une nouvelle instance pour la conversion. (Ce sera une conversion de référence à la place.)

J'espère que cela clarifie un peu les choses. Faites-le-moi savoir si cela n'a aucun sens!

Autres conseils

Ce n’est pas que Jon ne l’ait pas encore fait, mais voici quelques liens vers des blogs et des vidéos d’Eric Lippert. Il fait un bon travail en expliquant avec des exemples.

https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/

Les vidéos:

https://www.youtube.com/watch?v=3MQDrKbzvqU

https://www.youtube.com/watch?v=XRIadadaaBYlI

https://www.youtube.com/watch?v=St9d2EDZfrg

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