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?

Foi útil?

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

https://www.youtube.com/watch?v=XRIadQaBYlI

https://www.youtube.com/watch?v=St9d2EDZfrg

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top