2009-11-12 13 views
17

Vi un video sobre él en el canal 9 pero no lo entendí mucho.Comprensión de la covarianza y la contradicción en C# 4.0

¿Puede alguien darme un ejemplo simple sobre esto que sea fácil de entender? ¿Después de eso tal vez cómo se usaría en la práctica?

+2

¿Qué es el Canal 9? –

+2

http://channel9.msdn.com/ - Una colección de videos sobre marcos de desarrollo de microsoft, y mucho más :) – cwap

+0

Sí, es como un podcast, tiene algunos C# vids muy buenos con Anders, etc. –

Respuesta

8

Es posible que desee ver este blog, él hace un trabajo fantástico de explicarlo, pero creo que se necesitarán más ejemplos para aclararlo para las personas, ya que esto se convierte en un área muy difícil de entender, pero, la cita a continuación del artículo lo resume bien.

http://hestia.typepad.com/flatlander/2008/12/c-covariance-and-contravariance-by-example.html

"covarianza y contravarianza" significa que ahora puede pasar inexactas genéricos tipos cuando sea seguro hacerlo, al igual que puede pasar tipos de argumentos inexactos cuando es seguro hacerlo .

3

Eric Lippert le ocurrió una muy buena explicación en una reciente blog post

7

Un Tiger es un Animal por lo que se puede hacer cualquier cosa que un Animal puede hacer. Si tengo un método que pide un Animal, también puedo pasar un Tiger.

covarianza - Pasar un argumento de tipo más específico

Ésta es la dirección que está más familiarizado. Puedo pasar un IEnumerable<Tiger> en cualquier lugar que espere un IEnumerable<Animal>.


static void ListAnimals(IEnumerable<Animal> animals) 
{ 
} 

List<Tiger> tigers = new List<Tiger>(); 
ListAnimals(tigers); 

contravarianza - Pasar un argumento de tipo más general.

El 'contra' implica que esto va 'contra' el flujo de conversión normal. Este es más complicado porque parece contraintuitivo hasta que lo ves en acción.

Supongo que tengo una función que espera que se comparen un IComparer<Tiger> y dos tigres. La contradicción dice que también puedo pasar en el más general IComparer<Animal> porque puede también comparar dos tigres (ya que un Tigre ES un animal). Los compara de una manera más general, pero esto todavía es seguro.


static void CompareTigers(IComparer<Tiger> comparer, Tiger tiger1, Tiger tiger2) 
{ 
    comparer.Compare(tiger1, tiger2); 
} 

// normal - a tiger comparer can compare two tigers 
IComparer<Tiger> tigerComparer = null; 
CompareTigers(tigerComparer, new Tiger(), new Tiger()); 

// contravariance - an animal comparer can ALSO compare two tigers 
IComparer<Animal> animalComparer = null; 
CompareTigers(animalComparer, new Tiger(), new Tiger()); 

Tenga en cuenta que esto también funciona con los delegados. Puedo pasar un Action<Animal> en una función que espera un Action<Tiger> porque los objetos Tiger también se pueden pasar de manera segura al delegado Action<Animal>.

Cuestiones relacionadas