C #: Ist Variance (Kovarianz / Kontra) ein anderes Wort für Polymorphismus?
-
21-08-2019 - |
Frage
Ich versuche, die genaue Bedeutung der Worte, um herauszufinden, Covariance
und Contravariance
aus mehreren Artikeln online und Fragen auf Stackoverflow, und von dem, was ich verstehen kann, ist es nur ein anderes Wort für Polymorphismus .
Bin ich mit der obigen Aussage korrekt? Oder ich habe es nicht in Ordnung?
Lösung
Es ist sicherlich zu Polymorphismus verwendet. Ich würde nicht sagen, dass sie, obwohl nur „ein anderes Wort“ für Polymorphismus sind - sie sind über ganz bestimmte Situationen, in denen Sie eine Art behandeln, als ob es eine andere Art waren in einem bestimmten Kontext <. / p>
Zum Beispiel mit normalen Polymorphismus Sie zu einem Banana
eine Bezugnahme auf einen Fruit
als Referenz behandeln können - aber das bedeutet nicht, dass Sie ersetzen können Fruit
alle Mal, wenn Sie den Typen Banana
sehen. Zum Beispiel kann ein List<Banana>
nicht als List<Fruit>
behandelt werden, weil list.Add(new Apple())
gültig für List<Fruit>
ist aber nicht für List<Banana>
.
Kovarianz ermöglicht ein „größer“ (weniger spezifisch) Typen in einer API wechselt werden, wo der ursprüngliche Typ ist nur in einer „Ausgabe“ -Position (z.B. als Rückgabewert). Kontra ermöglicht ein „kleinere“ (spezifischeren) Typen in einer API wechselt werden, wo der ursprüngliche Typ ist nur in einer „Eingang“ Position verwendet wird.
Es ist schwer, in allen Details in einem einzigen SO Post zu gehen (obwohl hoffentlich jemand anderes einen besseren Job als dies tun!). Eric Lippert hat eine ausgezeichnete Reihe von Blog-Posts über sie .
Andere Tipps
Danke für all die Shout-outs, Jungs.
Jon und Rasmus Antworten sind in Ordnung, würde ich nur eine schnelle technische Notiz hinzufügen.
Wenn beiläufig und informell gesprochen, ja, nutzen die Menschen „Kovarianz“ und „Kontra“ auf eine bestimmte Art von Polymorphismus zu beziehen. Das heißt, die Art von Polymorphismus in dem Sie eine Folge von Spinnen behandeln, als ob es sich um eine Folge von Tieren waren.
wurden wir alle Computer-sciency bekommen und versuchen, mehr technische Definitionen zu machen, dann wahrscheinlich nicht sagen, ich würde das Kovarianz und Kontra sind „eine Art Polymorphismus“. Ich würde eine technische Definition wie folgt annähern:
Erstens, ich möchte anmerken, dass es zwei mögliche Arten von Polymorphismus in C #, die Sie sprechen könnte, und es ist wichtig, um sie nicht zu verwirren.
Die erste Art ist traditionell „Ad-hoc-Polymorphismus“ genannt, und das ist der Polymorphismus in dem Sie eine Methode M (Tier x) haben, und Sie passieren Spinnen und Giraffen und Wallabies, um es, und das Verfahren seiner einheitlich behandelt gebenen in die gleiche Art und Weise Argumente durch die Gemeinsamkeiten der Tierbasisklasse garantiert werden.
Die zweite Art ist traditionell „parametrischer Polymorphismus“ genannt, oder „generic Polymorphismus“. Das ist die Fähigkeit, eine generische Methode M<T>(T t)
zu machen und dann eine Reihe von Code in der Methode, die wiederum behandelt das Argument einheitlich auf Basis von Gemeinsamkeiten durch die Zwänge auf T gewährleistet.
Ich glaube, Sie reden über die erste Art von Polymorphismus. Aber mein Punkt ist nur, dass wir Polymorphismus als die Fähigkeit einer Programmiersprache zu verschiedene Dinge gleichmäßig auf einer bekannte Gemeinsamkeit basierten behandeln definieren können. (zum Beispiel eines bekannter Basistyp oder bekannte implementierte Schnittstelle.)
Kovarianz und Kontra ist die Fähigkeit einer Programmiersprache zu nutzt Gemeinsamkeiten zwischen generischen Typen von bekannten Gemeinsamkeiten ihrer Art Argumenten abgeleitet.
Sie können darüber nachdenken, Co- und Kontra als eine erweiterte Form von Polymorphismus zu sein. Sie können nicht nur eine Kind-Klasse verwenden, als ob es seine Eltern-Klasse, mit Co- und Kontra, der Polymorphismus erstreckt sich auf Klassen, die zu den polymorphen Klassen beziehen.
Stellen Sie sich zwei Klassen:
public class Pet { /*...*/ }
public class Cat:Pet { /*...*/ }
Polymorphismus ist in der Lage, eine Cat
als Pet
zu verwenden:
void Feed(Pet pet) { /* ... */ }
Cat cat = ...
Feed(cat);
Co- und Kontra werden verwendet, um in der Lage zu verwenden, um eine ICollection<Cat>
als ICollection<Pet>
(Kovarianz) zu sprechen:
void FeedAll(ICollection<Pet> pets) { /* ... */ }
List<Cat> cats = ...
FeedAll(cats);
oder ein Action<Pet>
als Action<Cat>
(Kontra) zu verwenden:
Action<Pet> GetFeeder() { /* ... */ }
Action<Cat> feeder = GetFeeder();
Eric Lippert hat eine große Blog-Serie darüber, wenn sie zum ersten Mal die Funktion der Gestaltung wurden. Teil eins ist hier .
Ich fand diese Sammlung:
Kovarianz und Kontra in C #, Part One
Kovarianz und Kontra in C #, Teil zwei: Matrixkovarianz
Kovarianz und Kontra in C #, Teil drei: Mitglieder-Gruppe Conversion Variance
Kovarianz und Kontra in C #, Vierter Teil: Tatsächlicher Delegate Variance
Kovarianz und Kontra In C #, Fünfter Teil: Funktionen höherer Ordnung Hurt My Brain
Kovarianz und Kontra in C #, Sechster Teil: Schnittstelle Variance
Kovarianz und Kontra in C # Teil sieben: Warum brauchen wir eine Syntax at All
?Kovarianz und Kontra in C #, Teil acht: Syntax Optionen
Kovarianz und Kontra in C #, Teil neun: Aktuelle Änderungen
Kovarianz und Kontra in C #, Teil Ten: Der Umgang mit Mehrdeutigkeit
Kovarianz und Kontra Teil Eleven: Bis zur Unendlichkeit, aber nicht darüber hinaus
Ich denke, ist besondere Art von Polymorphismus kein anderes Wort dafür. Es ist Polymorphismus in Delegierten , wo ein Delegierter mit einem Rückgabetyp Basis kann Kind Typen akzeptieren.