Ich lerne C # -Generika und mache Dummy-Code zu Testzwecken. Also teste ich das in Generic Modifier , die angibt, dass der Typparameter kontravariant ist.
Gegeben die folgende Schnittstelle:
%Vor%Beim Kompilieren bekomme ich die Fehlermeldung:
[CS1961] Ungültige Varianz: Der Typparameter 'T' muss invariant sein gültig für 'IInterfaceTest.Method (IList)'. "T" ist kontravariant.
Der Fehler bezieht sich nur auf die Zeile void Method(IEnumerable<T> values)
. Wenn diese Zeile entfernt wird, funktioniert alles einwandfrei.
Meine Frage ist also: Warum kann ich die generische Kontravariante mit IEnumerable
verwenden, aber nicht mit IList
? Habe ich etwas vergessen?
Danke.
Die Frage, warum IList<T>
nicht erlaubt ist, wurde bereits in den Kommentaren und verknüpften Fragen beantwortet: IList<T>
ist invariant in T
und daher kann eine kontravariante T
nicht hier verwendet werden.
Was mich zuerst verwirrt hat, ist die Tatsache, dass Method(IEnumerable<T>)
hier erlaubt ist. Das Seltsame ist, dass die Varianz "umgekehrt" ist , wenn Sie T
als Typargument für einen anderen generischen Typ verwenden.
Stellen Sie sich das vor.
%Vor% Nun sagt uns die Contravarianz von ITestInterface<in T>
in T
, dass Sie
Und wenn Sie lions.Method(e)
aufrufen, können Sie nur IEnumerable<Lion>
angeben. So kann der Code von Method
nur Lion
s aufzählen, die sind alle Animals
wie animals.Method()
erwartet. Alles ist gut.
Auf der anderen Seite ist IEnumerable<T> GetMethod()
illegal, weil:
ist legal, und jetzt würde gnu.GetMethod()
ein IEnumerable<Animal>
zurückgeben, wo Sie ein IEnumerable<Gnu>
erwarten würden. Und wenn du iteriert hast, könnten überraschende Tiere in dieser Reihenfolge warten.