=============
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
, Turtle
et Tiger
, avec les relations de sous - classement évidentes.
Supposons maintenant que vous ayez une méthode void M(ref Mammal m)
. M
peut à la fois lire et écrire m
.
Pouvez-vous passer une variable de type Animal
à M
?
Non. Cette variable peut contenir un Turtle
, mais M
supposera qu'elle ne contient que des mammifères. A Turtle
n'est pas un Mammal
.
Conclusion 1 : les ref
paramè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. M
Peut écrire m
et M
souhaitera peut-être écrire un Tiger
dans m
. Vous avez maintenant mis a Tiger
dans une variable qui est en fait de type Giraffe
.
Conclusion 2 : les ref
paramè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. N
Peut écrire n
et N
souhaitera peut-être écrire un fichier Tiger
.
Conclusion 3 : les out
paramètres ne peuvent pas être «plus petits».
Pouvez-vous passer une variable de type Animal
à N
?
Hmm.
Eh bien pourquoi pas? N
ne peut pas lire n
, il ne peut qu'écrire, non? Vous écrivez un Tiger
dans une variable de type Animal
et vous êtes tous ensemble, non?
Faux. La règle n'est pas " N
peut seulement écrire n
".
Les règles sont, brièvement:
1) N
doit écrire n
avant de N
retourner normalement. (En cas de N
lancers, tous les paris sont ouverts.)
2) N
doit écrire quelque chose dans n
avant de lire quelque chose à partir de n
.
Cela permet cette séquence d'événements:
- Déclarez un champ
x
de type Animal
.
- Passez
x
en out
paramètre à N
.
N
écrit un Tiger
dans n
, qui est un alias pour x
.
- Sur un autre fil, quelqu'un écrit un
Turtle
dansx
.
N
tente de lire le contenu de n
, et découvre un Turtle
dans ce qu'il pense être une variable de type Mammal
.
De toute évidence, nous voulons rendre cela illégal.
Conclusion 4 : les out
paramètres ne peuvent pas être rendus "plus grands".
Conclusion finale : ni ref
niout
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 .