Como é Covariance genérico e Contravariance Implementado em C # 4.0?
-
05-07-2019 - |
Pergunta
Eu não compareceu PDC 2008, mas ouvi algumas notícias que C # 4.0 é anunciado para apoiar covariância genérico e contra-variância. Ou seja, List<string>
pode ser atribuído a List<object>
. Como pode ser isso?
O livro de Jon Skeet Em C # in Depth , é explicado porque C # genéricos não suporta covariância e contra-variância. É principalmente para escrever código seguro. Agora, C # 4.0 alterado para apoiá-los. Poderia trazer caos?
Alguém sabe os detalhes sobre C # 4.0 pode dar alguma explicação?
Solução
Variação só será suportado em um segura maneira - na verdade, usando as habilidades que o CLR já tem. Assim, os exemplos eu dou no livro de tentar usar um List<Banana>
como um List<Fruit>
(ou o que fosse) ainda não vai funcionar - mas alguns outros cenários irá
Em primeiro lugar, ela só vai ser suportado por interfaces e delegados.
Em segundo lugar, requer o autor da interface / delegado para decorar os parâmetros de tipo como in
(para contravariance) ou out
(para covariância). O exemplo mais óbvio é IEnumerable<T>
que sempre apenas permite tirar valores "fora" dela - ele não permite que você adicionar novos. Que se tornará IEnumerable<out T>
. Que faz segurança de tipo não dói nada, mas permite que você retornar um IEnumerable<string>
a partir de um método declarado para retornar IEnumerable<object>
por exemplo.
Contravariance é mais difícil de dar exemplos concretos para o uso de interfaces, mas é fácil com um delegado. Considere Action<T>
- que representa apenas um método que leva um parâmetro T
. Seria bom para ser capaz de converter facilmente usar um Action<object>
como um Action<string>
- qualquer método que leva um parâmetro object
vai ser bom quando ele é apresentado com um string
vez. Claro, C # 2 já tem de covariância e contravariância de delegados, em certa medida, mas através de uma conversão real a partir de um tipo de delegado a outro (a criação de uma nova instância) - ver P141-144 para exemplos. C # 4 irá tornar isso mais genérico, e (creio eu) irá evitar a criação de uma nova instância para a conversão. (Vai ser uma conversão de referência em vez disso.)
Espero que isso esclarece tudo um pouco - por favor, deixe-me saber se isso não faz sentido
Outras dicas
Não que Jon não tenha já cobriu, mas aqui estão alguns links para blogs e vídeos de Eric Lippert. Ele faz um bom trabalho de explicar com exemplos.
https://blogs.msdn.microsoft.com/ericlippert/2007/10/16/covariance-and-contravariance-in-c-part-one/
Os vídeos:
https://www.youtube.com/watch?v=3MQDrKbzvqU