=============
MISE À JOUR: J'ai utilisé cette réponse comme base pour cette entrée de blog:
Pourquoi les paramètres ref et out ne permettent-ils pas la variation de type?
Consultez la page du blog pour plus de commentaires sur ce problème. Merci pour la bonne question.
=============
Supposons que vous avez des classes Animal, Mammal, Reptile, Giraffe, Turtleet Tiger, avec les relations de sous - classement évidentes.
Supposons maintenant que vous ayez une méthode void M(ref Mammal m). Mpeut à la fois lire et écrire m.
Pouvez-vous passer une variable de type Animalà M?
Non. Cette variable peut contenir un Turtle, mais Msupposera qu'elle ne contient que des mammifères. A Turtlen'est pas un Mammal.
Conclusion 1 : les refparamètres ne peuvent pas être «agrandis». (Il y a plus d'animaux que de mammifères, donc la variable devient "plus grosse" car elle peut contenir plus de choses.)
Pouvez-vous passer une variable de type Giraffeà M?
Non. MPeut écrire met Msouhaitera peut-être écrire un Tigerdans m. Vous avez maintenant mis a Tigerdans une variable qui est en fait de type Giraffe.
Conclusion 2 : les refparamètres ne peuvent pas être rendus "plus petits".
Considérez maintenant N(out Mammal n).
Pouvez-vous passer une variable de type Giraffeà N?
Non. NPeut écrire net Nsouhaitera peut-être écrire un fichier Tiger.
Conclusion 3 : les outparamètres ne peuvent pas être «plus petits».
Pouvez-vous passer une variable de type Animalà N?
Hmm.
Eh bien pourquoi pas? Nne peut pas lire n, il ne peut qu'écrire, non? Vous écrivez un Tigerdans une variable de type Animalet vous êtes tous ensemble, non?
Faux. La règle n'est pas " Npeut seulement écrire n".
Les règles sont, brièvement:
1) Ndoit écrire navant de Nretourner normalement. (En cas de Nlancers, tous les paris sont ouverts.)
2) Ndoit écrire quelque chose dans navant de lire quelque chose à partir de n.
Cela permet cette séquence d'événements:
- Déclarez un champ
xde type Animal.
- Passez
xen outparamètre à N.
Nécrit un Tigerdans n, qui est un alias pour x.
- Sur un autre fil, quelqu'un écrit un
Turtledansx .
Ntente de lire le contenu de n, et découvre un Turtledans ce qu'il pense être une variable de type Mammal.
De toute évidence, nous voulons rendre cela illégal.
Conclusion 4 : les outparamètres ne peuvent pas être rendus "plus grands".
Conclusion finale : ni refniout les paramètres peuvent varier leurs types. Faire autrement, c'est briser la sécurité de type vérifiable.
Si ces problèmes de théorie de base des types vous intéressent, envisagez de lire ma série sur le fonctionnement de la covariance et de la contravariance en C # 4.0 .