=============
AGGIORNAMENTO: ho usato questa risposta come base per questo post di blog:
Perché i parametri ref e out non consentono la variazione del tipo?
Vedi la pagina del blog per ulteriori commenti su questo problema. Grazie per l'ottima domanda.
=============
Supponiamo di avere classi Animal, Mammal, Reptile, Giraffe, Turtlee Tiger, con le relazioni sottoclasse evidenti.
Supponiamo ora di avere un metodo void M(ref Mammal m). Mpuò sia leggere che scrivere m.
Puoi passare una variabile di tipo Animala M?
No. Quella variabile potrebbe contenere un Turtle, ma Msupporrà che contenga solo Mammiferi. A Turtlenon è un Mammal.
Conclusione 1 : i refparametri non possono essere "ingranditi". (Ci sono più animali che mammiferi, quindi la variabile sta diventando "più grande" perché può contenere più cose.)
Puoi passare una variabile di tipo Giraffea M?
No. Mpuò scrivere me Mpotrebbe voler scrivere a Tigerin m. Ora hai inserito a Tigerin una variabile che è in realtà di tipo Giraffe.
Conclusione 2 : i refparametri non possono essere "più piccoli".
Adesso considera N(out Mammal n).
Puoi passare una variabile di tipo Giraffea N?
No. Npuò scrivere ne Npotrebbe voler scrivere a Tiger.
Conclusione 3 : i outparametri non possono essere "più piccoli".
Puoi passare una variabile di tipo Animala N?
Hmm.
Beh perchè no? Nnon riesco a leggere n, può solo scrivergli, giusto? Scrivi Tigera una variabile di tipo Animale sei pronto, giusto?
Sbagliato. La regola non è " Npuò solo scrivere n".
Le regole sono, brevemente:
1) Ndeve scrivere nprima di Nrestituire normalmente. (Se Nviene lanciato, tutte le scommesse sono disattivate.)
2) Ndeve scrivere qualcosa nprima di leggere qualcosa da n.
Ciò consente questa sequenza di eventi:
- Dichiarare un campo
xdi tipo Animal.
- Passa
xcome outparametro a N.
Nscrive a Tigerin n, che è un alias per x.
- Su un altro thread, qualcuno scrive a
Turtlein x.
Ntenta di leggere il contenuto ne scopre a Turtlein ciò che pensa sia una variabile di tipo Mammal.
Chiaramente vogliamo renderlo illegale.
Conclusione 4 : i outparametri non possono essere "ingranditi".
Conclusione finale : Né refné outparametri possono variare i loro tipi. Fare altrimenti significa rompere la sicurezza verificabile del tipo.
Se questi problemi nella teoria dei tipi di base ti interessano, potresti leggere le mie serie su come funzionano la covarianza e la contravarianza in C # 4.0 .