=============
ATUALIZAÇÃO: usei esta resposta como base para esta entrada do blog:
Por que os parâmetros ref e out não permitem variação de tipo?
Veja a página do blog para mais comentários sobre esse assunto. Obrigado pela ótima pergunta.
=============
Vamos supor que você tem aulas Animal, Mammal, Reptile, Giraffe, TurtleeTiger , com os relacionamentos subclassificação óbvias.
Agora, suponha que você tenha um método void M(ref Mammal m). Mpode ler e escrever m.
Você pode passar uma variável do tipo Animalpara M?
Não. Essa variável pode conter a Turtle, mas Massumirá que ela contém apenas mamíferos. A Turtlenão é a Mammal.
Conclusão 1 : refparâmetros não podem ser "maiores". (Existem mais animais que mamíferos, a variável está ficando "maior" porque pode conter mais coisas.)
Você pode passar uma variável do tipo Giraffepara M?
Não Mpode escrever para m, e Mpode querer escrever uma Tigerem m. Agora você colocou um Tigerem uma variável que é realmente do tipo Giraffe.
Conclusão 2 : os refparâmetros não podem ser "menores".
Agora considere N(out Mammal n).
Você pode passar uma variável do tipo Giraffepara N?
Não. NPode escrever para ne Npode querer escrever a Tiger.
Conclusão 3 : os outparâmetros não podem ser "menores".
Você pode passar uma variável do tipo Animalpara N?
Hmm.
Bem, porque não? Nnão pode ler n, só pode escrever, certo? Você escreve a Tigerpara uma variável do tipo Animale está tudo pronto, certo?
Errado. A regra não é " Nsó pode escrever para n".
As regras são, brevemente:
1) Ntem que escrever nantes de Nretornar normalmente. (Se Njogar, todas as apostas estão desativadas.)
2) Ntem que escrever algo nantes de ler algo n.
Isso permite esta sequência de eventos:
- Declare um campo
xdo tipo Animal.
- Passe
xcomo um outparâmetro para N.
Nescreve a Tigerinto n, que é um alias para x.
- Em outro segmento, alguém escreve um
Turtlepara x.
Ntenta ler o conteúdo de ne descobre um Turtleno que ele acha que é uma variável do tipo Mammal.
Claramente, queremos tornar isso ilegal.
Conclusão 4 : os outparâmetros não podem ser "maiores".
Conclusão final : Nem refnem outparâmetros podem variar seus tipos. Fazer o contrário é quebrar a segurança do tipo verificável.
Se essas questões na teoria básica de tipos lhe interessam, considere ler minha série sobre como a covariância e a contravariância funcionam no C # 4.0 .