Warum kann eine Liste eines Schnittstellentyps Instanzen einer erbenden Schnittstelle nicht akzeptieren? [Duplikat]

8

Gegeben die folgenden Typen:

%Vor%

Warum kann ich das nicht tun?

%Vor%

Dies führt zu folgendem Kompilierungsfehler:

  

Der Argumenttyp 'System.Collections.Generic.List' kann nicht dem Parametertyp 'System.Collections.Generic.List' zugewiesen werden

Ich verstehe den Fehler und stelle fest, dass es Umgehungslösungen gibt. Ich sehe keinen klaren Grund, warum diese direkte Umwandlung nicht erlaubt ist. Die Werte, die in einer Liste von ISecondary enthalten sind, sollten (nach Erweiterung) Werte vom Typ IPrimary sein. Warum werden dann List<IPrimary> und List<ISecondary> als nicht verwandte Typen interpretiert?

Kann jemand die Gründe dafür, dass C # so entworfen wird, klar erläutern?

Ein etwas erweitertes Beispiel: Ich stieß auf das Problem, als ich versuchte, etwas Ähnliches wie das folgende zu tun:

%Vor%     
Kjartan 31.01.2013, 08:42
quelle

4 Antworten

6
  

Warum kann ich das nicht tun? List<IPrimary> list = new List<ISecondary>();

Stellen Sie sich vor, Sie hätten eine Methode wie folgt definiert:

%Vor%

Was würde passieren, wenn Sie einen List<ISecondary> als Parameter übergeben würden?

Der Fehler, dass List<ISecondary> nicht von List<IPrimary> zugewiesen werden kann, ist die Art und Weise, wie der Compiler Sie aus solchen Schwierigkeiten herausholt.

    
GolfWolf 31.01.2013, 08:50
quelle
10
%Vor%

Und deshalb.

    
Matthew Watson 31.01.2013 08:53
quelle
4
%Vor%

Es schützt Sie vor einem Fehler. Die Listeninstanz (das Objekt) fordert sekundäre Instanzen an. Nicht jede primäre ist eine sekundäre. Es wird jedoch erwartet, dass eine Primärliste jede primäre enthalten kann. Wenn wir eine Liste von sekundären als eine Liste von primären behandeln könnten: schlechte Dinge.

Eigentlich erlauben Arrays do dies - und einen Fehler zur Laufzeit, wenn Sie falsch liegen.

    
Marc Gravell 31.01.2013 08:50
quelle
1

Der Grund, dass Listentypen in ihrem generischen Parameter nicht kovariant sind, dh dass List<ISecondary> kein Subtyp von List<IPrimary> ist, ist, dass sie read-write sind. In Ihrem erweiterten Beispiel könnte Ihre Methode AcceptList list.Add(x) verwenden, wobei x eine IPrimary ist, aber keine ISecondary .

Beachten Sie, dass IEnumerable<T> korrekt kovariant ist, während Arrays kovariant typisiert sind (Sie können das tun, was Sie oben versuchen), aber aus dem gleichen Grund ist das kein Sound - das Hinzufügen eines Elements zur Sammlung wird zur Laufzeit fehlschlagen.

    
Nicholas W 31.01.2013 08:51
quelle

Tags und Links