=============
AKTUALIZACJA: Użyłem tej odpowiedzi jako podstawy dla tego wpisu na blogu:
Dlaczego parametry ref i out nie pozwalają na zmianę typu?
Więcej komentarzy na ten temat znajdziesz na blogu. Dzięki za świetne pytanie.
=============
Załóżmy, że masz zajęcia Animal, Mammal, Reptile, Giraffe, Turtlei Tiger, z oczywistych relacji podklasy.
Teraz przypuśćmy, że masz metodę void M(ref Mammal m). Mpotrafi zarówno czytać, jak i pisać m.
Czy możesz przekazać zmienną typu Animaldo M?
Nie. Ta zmienna może zawierać a Turtle, ale Mzakłada, że zawiera tylko ssaki. A Turtlenie jest Mammal.
Wniosek 1 : refparametrów nie można „zwiększyć”. (Jest więcej zwierząt niż ssaków, więc zmienna staje się „większa”, ponieważ może zawierać więcej rzeczy).
Czy możesz przekazać zmienną typu Giraffedo M?
Nie. MMoże pisać do mi Mmoże chcieć napisać Tigerdo m. Teraz wstawiłeś a Tigerdo zmiennej, która jest faktycznie typu Giraffe.
Wniosek 2 : refparametrów nie można uczynić „mniejszymi”.
A teraz zastanów się N(out Mammal n).
Czy możesz przekazać zmienną typu Giraffedo N?
Nie. NMoże pisać do ni Nmoże chcieć napisać Tiger.
Wniosek 3 : outparametrów nie można uczynić „mniejszymi”.
Czy możesz przekazać zmienną typu Animaldo N?
Hmm.
Czemu nie? Nnie może czytać n, może tylko pisać, prawda? Piszesz a Tigerdo zmiennej typu Animali wszystko gotowe, prawda?
Źle. Zasada nie brzmi: „ Nmożna tylko pisać n”.
Zasady są w skrócie:
1) Nmusi napisać nprzed Npowrotem normalnie. (Jeśli Nrzuca, wszystkie zakłady są anulowane.)
2) Nmusi coś napisać, nzanim coś przeczyta n.
To pozwala na taką sekwencję wydarzeń:
- Zadeklaruj pole
xtypu Animal.
- Przekaż
xjako outparametr do N.
Nzapisuje Tigerdo n, który jest aliasem dla x.
- W innym wątku ktoś pisze
Turtledo x.
Npróbuje odczytać zawartość ni Turtleznajduje zmienną typu, jak uważa Mammal.
Oczywiście chcemy uczynić to nielegalnym.
Wniosek 4 : outparametrów nie można uczynić „większymi”.
Wniosek końcowy : Ani parametry, refani outparametry nie mogą różnić się typami. W przeciwnym razie należy złamać weryfikowalne bezpieczeństwo typów.
Jeśli te kwestie w podstawowej teorii typów Cię interesują, rozważ przeczytanie mojej serii o tym, jak działają kowariancja i kontrawariancja w C # 4.0 .