=============
UPDATE: Ich habe diese Antwort als Grundlage für diesen Blogeintrag verwendet:
Warum erlauben ref- und out-Parameter keine Typvariation?
Weitere Kommentare zu diesem Thema finden Sie auf der Blog-Seite. Danke für die tolle Frage.
=============
Nehmen wir an , Sie haben Klassen Animal
, Mammal
, Reptile
, Giraffe
, Turtle
und Tiger
, mit den offensichtlichen Subklassifizieren Beziehungen.
Angenommen, Sie haben eine Methode void M(ref Mammal m)
. M
kann sowohl lesen als auch schreiben m
.
Können Sie eine Variable vom Typ passieren Animal
zu M
?
Nein. Diese Variable könnte a enthalten Turtle
, geht jedoch M
davon aus, dass sie nur Säugetiere enthält. A Turtle
ist nicht a Mammal
.
Schlussfolgerung 1 : ref
Parameter können nicht "größer" gemacht werden. (Es gibt mehr Tiere als Säugetiere, daher wird die Variable "größer", weil sie mehr Dinge enthalten kann.)
Können Sie eine Variable vom Typ passieren Giraffe
zu M
?
Nein M
kann schreiben m
, und M
vielleicht einen schreiben wollen Tiger
in m
. Jetzt haben Sie ein Tiger
in eine Variable eingefügt, die tatsächlich vom Typ ist Giraffe
.
Schlussfolgerung 2 : ref
Parameter können nicht "kleiner" gemacht werden.
Nun überlegen Sie N(out Mammal n)
.
Können Sie eine Variable vom Typ passieren Giraffe
zu N
?
Nein, N
kann schreiben n
und N
möchte vielleicht eine schreiben Tiger
.
Schlussfolgerung 3 : out
Parameter können nicht "kleiner" gemacht werden.
Können Sie eine Variable vom Typ passieren Animal
zu N
?
Hmm.
Gut, warum nicht? N
kann nicht lesen n
, es kann nur darauf schreiben, oder? Du schreibst eine Tiger
in eine Variable vom Typ Animal
und bist fertig, oder?
Falsch. Die Regel lautet nicht " N
kann nur schreiben n
".
Die Regeln sind kurz:
1) N
muss schreiben, n
bevor N
normal zurückgegeben wird. (Bei N
Würfen sind alle Wetten ungültig.)
2) N
muss etwas schreiben, n
bevor es etwas liest n
.
Das erlaubt diese Abfolge von Ereignissen:
- Deklarieren Sie ein Feld
x
vom Typ Animal
.
- Übergeben Sie
x
als out
Parameter N
.
N
schreibt ein Tiger
in n
, was ein Alias für ist x
.
- In einem anderen Thread schreibt jemand ein
Turtle
in x
.
N
versucht, den Inhalt von zu lesen n
, und entdeckt Turtle
eine Variable, die seiner Meinung nach vom Typ ist Mammal
.
Natürlich wollen wir das illegal machen.
Schlussfolgerung 4 : out
Parameter können nicht "größer" gemacht werden.
Endgültige Schlussfolgerung : Weder ref
noch out
Parameter dürfen ihre Typen variieren. Andernfalls wird die überprüfbare Typensicherheit verletzt.
Wenn Sie diese Probleme in der grundlegenden Typentheorie interessieren, lesen Sie meine Reihe darüber, wie Kovarianz und Kontravarianz in C # 4.0 funktionieren .