2008-11-07 12 views
5

Was bedeuten die Begriffe "Kovarianz" und "Kontravarianz"?Kovarianz vs. Kontravarianz in Bezug auf Klassenvererbung

Gegeben 2 Klassen, Tier und Elefant (die von Tiere erbt), mein Verständnis ist, dass Sie einen Laufzeitfehler erhalten würden, wenn Sie einen Elefanten in eine Reihe von Tiere versuchen und setzen, und Das passiert, weil Elephant "größer" (genauer) als Animal ist. Aber könntest du ein Tier in eine Reihe von Elefanten legen, wenn du siehst, dass Elephant garantiert die Animal-Eigenschaften enthält?

+0

Nützliches: http://blogs.msdn.com/ericlippert/archive/2007/10/16/covariance-and-contravariance-in-c-part-one.aspx –

+0

[Kovarianzstrukturen vs Kontra] (http://izlooite.blogspot.com/2011/04/covariance-and-contravariance.html) –

Antwort

9

Sie haben nach hinten es. Sie können einen Elefanten zu einem Tier-Array hinzufügen, weil es ist ein Tier, und es ist garantiert, alle Methoden, die ein Tier haben muss. Sie können kein Tier zu einem Elephant-Array hinzufügen, weil es nicht alle Methoden, die ein Elephant haben muss, hat.

Der Wikipedia-Artikel über covariance and contravariance eine gute Erklärung dafür hat:

Im Typsystem einer Programmiersprache, ein Betreiber von Typ Typen kovariant, wenn sie die Ordnung bewahrt, ≤, von Typen, welche Ordertypen von spezifischeren zu allgemeineren Typen ordnet; es ist kontravariant, wenn es diese Reihenfolge umkehrt. Wenn keiner von beiden zutrifft, ist der Operator invariant. Diese Begriffe stammen aus der Kategorientheorie.

Auch Sie sagten, dass Typ Elefant "größer" war, und das ist nicht der Fall. Typ Tier ist "größer" in dem Sinne, dass es spezifischere Typen wie Elefanten, Giraffen und Löwen enthält.

+0

Ah, das macht Sinn, also würden Sie sagen, dass ein Elefant zu einem Tier kovariant ist, aber ein Tier gegen einen Elefanten kontravariant ist? – alexmac

+0

Es hängt davon ab, was Sie mit den Typen machen. Die Methoden von Elephant müssen denselben oder einen engeren Typ wie Animals Methoden zurückgeben (sie könnten Animal oder Elephant zurückgeben, wenn die Animal-Methode Animal zurückgibt). Das würde man kovariant nennen. –

+0

Aber die Methodenparameter von Elephants Methoden müssen gleich oder breiter sein als die Methoden von Animal. Dies ist eine Kontravarianz. –

0

Sie sollten versuchen, Seiten 45-49 von Introducing .NET 4.0 With Visual Studio 2010 zu lesen, die sich mit genau diesem Beispiel beschäftigen. Es hat sogar ein paar schöne Fotos von Elefanten.

Der wichtigste Punkt nehmen heißt, diese

var things = new List<IThing<IContent>> { new ConcreteThing() } 

mit dem tun:

public class ConcreteThing : IThing<ConcreteContent> 
{ 

} 

müssen Sie die „out“ in der Schnittstellendefinition, die spezifischeren Formen ermöglicht werden gesetzt, aber alles, was aus IThing ausgelesen wird, muss garantiert der allgemeinere Typ sein.

public interface IThing<out T> where T : IContent 
{ 
}