2009-11-12 14 views
17

Ich habe ein Video darüber auf Channel 9 angeschaut, aber ich habe es nicht wirklich verstanden.Kovarianz und Kontravarianz in C# 4.0 verstehen

Kann mir bitte jemand ein einfaches Beispiel geben, das leicht zu verstehen ist? Danach vielleicht, wie es in der Praxis verwendet würde?

+2

Was ist Kanal 9? –

+2

http://channel9.msdn.com/ - Eine Sammlung von Videos über Microsoft-Entwicklung Frameworks und vieles mehr :) – cwap

+0

Ja, es ist wie ein Podcast, hat einige wirklich gute C# vids mit Anders, etc. –

Antwort

8

Vielleicht möchten Sie sich dieses Blog ansehen, er erklärt es fantastisch, aber ich denke, es wird mehr Beispiele brauchen, um es für die Menschen zu klären, da dies in ein sehr schwer verständliches Gebiet gerät, aber das Zitat unten aus dem Artikel fasst es gut zusammen.

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

„Kovarianz und Kontra“ bedeutet , die Sie jetzt ungenauen generic Arten passieren kann, wenn es sicher ist, dies zu tun, so wie Sie ungenauen Argumenttypen passieren kann, wenn es sicher ist, dies zu tun .

3

Eric Lippert kam kürzlich in einem blog post

7

A Tiger mit einer sehr guten Erklärung oben ist ein Animal so kann es alles tun, ein Animal tun kann. Wenn ich eine Methode habe, die nach einer Animal fragt, kann ich auch eine Tiger übergeben.

Kovarianzstrukturen - Dieses

einen spezifischeren Typ Argument übergeben die Richtung, die Sie am besten vertraut sind. Ich kann eine IEnumerable<Tiger> überall passieren, die eine IEnumerable<Animal> erwartet.


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

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

Kontra - Passing eine allgemeinere Art Argument.

Der "Contra" bedeutet, dass dies dem normalen Umwandlungsfluss entgegensteht. Dieser ist trickreicher, weil er scheinbar intuitiv ist, bis man ihn in Aktion sieht.

Angenommen, ich habe eine Funktion, die erwartet, dass ein IComparer<Tiger> und zwei Tiger verglichen werden. Contravariance sagt, dass ich auch die allgemeinere IComparer<Animal> weitergeben kann, weil es auch zwei Tiger vergleichen kann (da ein Tiger IS ein Tier ist). Es vergleicht sie auf eine allgemeinere Art, aber das ist immer noch typsicher.


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

Beachten Sie, dass dies mit den Delegierten auch funktioniert. Ich kann eine in eine Funktion übergeben, die eine Action<Tiger> erwartet, weil Tiger Objekte auch sicher an die Delegierten Action<Animal> übergeben werden können.