Frage

Was ist die Bedeutung der Begriffe ‚Kovarianz‘ und ‚Kontra‘?

Bei zwei Klassen, Animal und Elephant (die erbt von Animal ), mein Verständnis ist, dass Sie einen Laufzeitfehler erhalten würde wenn Sie versuchen, einen Elefanten in eine Reihe von Tieren zu setzen, und dies geschieht, weil Elephant ist „größer“ (spezifische) als Tier. Aber könnten Sie ein Tier in ein Array von Elephant platzieren, zu sehen, wie Elephant garantiert die Tiereigenschaften enthalten?

War es hilfreich?

Lösung

Sie haben es rückwärts. Sie können einen Elefanten zu einem Tier-Array hinzugefügt werden, da es ist ein Tier, und es ist garantiert alle Methoden haben ein Tier erforderlich ist, zu haben. Sie können kein Tier zu einem Elefanten-Array hinzugefügt werden, da es funktioniert nicht haben alle Methoden, die ein Elefant haben muß.

Der Wikipedia-Artikel über Kovarianz und Kontra eine gute Erklärung dafür hat:

  

Im Rahmen des Typsystem einer Programmiersprache, ein Betreiber von Typen Typen kovariant, wenn sie die Ordnung bewahrt, ≤, von Typen, die Typen von speziellere zu allgemeineren diejenigen anordnet; es ist kontra wenn es diese Reihenfolge umkehrt. Wenn keiner dieser Fälle ist der Betreiber invariant. Diese Begriffe kommen aus der Kategorie Theorie.

Auch sagten Sie, dass Typ-Elefant war „größer“, und dies ist nicht der Fall. Tier Typ ist „größer“ in dem Sinne, dass es bestimmte Arten umfasst, wie Elefanten, Giraffe und Löwen.

Andere Tipps

Haben Sie einen Blick auf diese Übersicht über die Kovarianz und Kontra in C # 4.0 und sehen, ob das hilft:

http://blogs.msdn.com/charlie/archive/2008/10/27/linq-farm-covariance-and-contravariance-in-visual-studio-2010.aspx

Sie sollten versuchen, Seiten lesen 45-49 von .NET 4.0 mit Visual Studio 2010 Einführung die sich mit genau diesem Beispiel. Es hat sogar ein paar schöne Fotos von Elefanten.

Der wichtigste Punkt nehmen heißt, dies zu tun

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

mit:

public class ConcreteThing : IThing<ConcreteContent>
{

}

Sie müssen die „out“ in der Schnittstellendefinition, die spezifischeren Formen können eingestellt werden, aber alles aus IThing lesen muss die allgemeinere Art garantiert werden.

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

public interface IGoOut<out T>
{
    T Func();
}
public interface IComeIn<in T>
{
    void Action(T obj);
}
public class GoOutClass<T>:IGoOut<T>
{
    public T Func()
    {
        return default(T);
    }
}

public class ComeInClass<T> : IComeIn<T>
{
    public void Action(T obj) {  }
}

==========================================================
object obj = null;
//Covariance Example [Array +  IEnumerable<T> +  IEnumerator<T>  +  IInterface<Out T>  +  Func<T>]
object[] array = (string[]) obj;
IEnumerable<object> enumerable = (IEnumerable<string>) obj;
IEnumerator<object> enumerator = (IEnumerator<string>)obj;
IGoOut<object> goOut = (GoOutClass<string>)obj;
Func<object> func = (Func<string>)obj;


//Contravariance Example[IInterface<in T>]
IComeIn<string> comeIn = (ComeInClass<object>) obj;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top