Por que precisamos de novas palavras-chave para Covariância e Contravariance em C #?
-
06-07-2019 - |
Pergunta
Alguém pode explicar porque é que há a necessidade de adicionar um out ou no parâmetro para indicar que um tipo genérico é Co ou variante Contra em C # 4.0?
Eu tenho tentado entender por que isso é importante e por que o compilador não pode simplesmente descobrir isso ..
Obrigado,
Josh
Solução
Eric Lippert, que trabalha no langauge, tem uma série de posts sobre MSDN que deve ajudar a esclarecer as questões envolvidas:
http://blogs.msdn.com/ericlippert/ arquivo / tags / Covariance + e + Contravariance / default.aspx
Ao ler os artigos mostrados nesse link, começar de baixo e trabalhar para cima.
Eventualmente, você vai chegar a # 7 (Por que precisamos de uma sintaxe em tudo?) .
Outras dicas
Nós realmente não necessidade -los, mais então precisamos abstract
em classes ou ambos out
e ref
. Eles existem apenas para que nós, como programadores, pode fazer o nosso cristal intenção clara, de modo que programador de manutenção sabemos o que estamos fazendo, e o compilador pode verificar que estamos fazendo certo.
Bem, o principal problema é que se você tem uma hierarquia de classes como:
class Foo { .. }
class Bar : Foo { .. }
E você tem um IEnumerator<Bar>
, você não pode usar isso como uma IEnumerator<Foo>
mesmo que isso seria perfeitamente seguro. Em 3,5 essa força um grande número de giros dolorosas. Esta operação seria sempre seguro, mas é negado pelo sistema tipo porque ele não sabe sobre o uso covariant do parâmetro de tipo genérico. IEnumerator<Bar>
só pode retornar um Bar
e cada Bar
é um Foo
.
Da mesma forma, se você tivesse um IEqualityComparer<Foo>
ele pode ser usado para comparar qualquer par de objetos do tipo Foo
mesmo se um ou ambos é um Bar
, mas não pode ser convertido em um IEqualityComparer<Bar>
porque ele não sabe sobre o uso contravariant do parâmetro de tipo genérico. IEqualityComparer<Foo>
consome apenas objetos do tipo Foo
e cada Bar
é um Foo
.
Sem estas palavras-chave que é forçado a assumir o argumento genérico pode ocorrer tanto como um argumento para um método e como o tipo de resultado de um método, e por isso não podemos permitir com segurança uma das conversões acima.
Com eles, o tipo de sistema é livre para nos permitir com segurança upcast e abatido entre essas interfaces na direção indicada pela palavra-chave e nós obter erros indicando quando violaria a disciplina necessária para garantir que a segurança.
As palavras-chave in
e out
ter sido palavras-chave desde C # 1.0, e têm sido utilizados no contexto de parâmetros in
- e out
- a métodos.
Covariância e contravariance são restrições sobre como se pode implementar uma interface. Não há nenhuma boa maneira de inferir-los -. A única maneira, eu acho, é de uso, e que seria confuso e no final ele não iria funcionar
Jon e Joel ambos forneceu uma resposta muito completa para isso, mas a linha de fundo é que eles não são tanto necessário pelo compilador mas sim garantia ajuda a segurança da aplicação, indicando explicitamente a variação do parâmetro. Isto segue um padrão muito semelhante ao que exige a palavra-chave out
ou ref
tanto no sítio de vocalização eo local declaração.