2009-11-12 6 views
17

Ho visto un video su Canale 9 ma non l'ho capito molto.Capire covarianza e controvarianza in C# 4.0

Qualcuno può darmi un semplice esempio su questi che è facile da capire? Dopo quello forse come sarebbe usato nella pratica?

+2

Che cos'è il canale 9? –

+2

http://channel9.msdn.com/ - Una raccolta di video su framework di sviluppo Microsoft e molto altro :) – cwap

+0

Sì, è come un podcast, ha dei buoni v # cid con Anders, ecc. –

risposta

8

Si potrebbe voler guardare questo blog, fa un fantastico lavoro di spiegarlo, ma penso che ci vorranno più esempi per chiarirlo per le persone, poiché questo entra in un'area molto difficile da capire, ma, la citazione qui sotto dall'articolo lo riassume bene.

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

"covarianza e controvarianza" significa che ora è possibile passare inesatte generici tipi quando è sicuro di farlo, proprio come è possibile passare tipi di argomenti inesatti quando è sicuro di farlo .

3

Eric Lippert si avvicinò con una spiegazione molto buona in una recente blog post

7

Un Tiger è un Animal in modo che possa fare qualsiasi cosa un Animal può fare. Se ho un metodo che richiede un Animal posso anche passare in un Tiger.

covarianza - Il passaggio di un tipo più specifico argomento

Questa è la direzione si sono più familiarità con. Posso passare un IEnumerable<Tiger> ovunque che si aspetta un IEnumerable<Animal>.


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

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

controvarianza - Il passaggio di un argomento più generale del tipo.

Il "contra" implica che questo va "contro" il normale flusso di conversione. Questo è più complicato perché sembra anti-intuitivo finché non lo vedi in azione.

Dire che ho una funzione che si aspetta un IComparer<Tiger> e due tigri da confrontare. La controvarianza dice che posso anche passare al più generale IComparer<Animal> perché può anche confrontare due tigri (dal momento che una Tigre è un animale). Le confronta in un modo più generale, ma questo è ancora sicuro.


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()); 

Nota che questo funziona anche con i delegati. Posso passare un Action<Animal> a una funzione che si aspetta un Action<Tiger> perché gli oggetti Tiger possono anche essere passati in modo sicuro al delegato Action<Animal>.