Warum kann ich ein Dictionary eines Werttyps nicht in ein Dictionary eines anderen Werttyps umwandeln, wenn die Werttypen voneinander umgewandelt werden können? [Duplikat]

7

Warum funktioniert das nicht?

%Vor%

Ist das ein Fehler im Dictionary Casting-Mechanismus oder in meinem Denken, dass dies erlaubt sein sollte?

Danke.

    
user420667 19.12.2011, 20:34
quelle

3 Antworten

20
  

Ist das ein Fehler im Wörterbuch-Casting-Mechanismus oder in meinem Denken, dass dies erlaubt sein sollte?

In deinem Denken. Sie erwarten, dass Wörterbücher in ihren Conversions kovariant sein sollten. Sie sind nicht, aus dem folgenden Grund. Angenommen, sie waren und folgern, was schief gehen könnte:

%Vor%

Ein String-Array kann in IEnumerable<string> umgewandelt werden, nicht jedoch in List<string> . Sie fügen etwas, das nicht ist , eine Liste von Strings in ein Dictionary ein, das nur eine String-Liste aufnehmen kann.

In C # können generische Typen kovariant oder kontravariant sein, wenn alle folgenden Bedingungen erfüllt sind:

  • Sie verwenden C # 4 oder besser.
  • Der variierende generische Typ ist eine Schnittstelle oder ein Delegat.
  • Die Varianz ist nachweisbar typsicher. (Die C # -Spezifikation beschreibt die Regeln, die wir zur Bestimmung der Varianzsicherheit verwenden. C # 4.0-Version doc-Datei kann heruntergeladen werden [hier] . Siehe Abschnitt 23.5.)
  • Die Typenargumente, die variieren, sind alle Referenztypen.
  • Der Typ wurde ausdrücklich als sicher für Abweichungen gekennzeichnet.

Die meisten dieser Bedingungen sind für das Wörterbuch nicht erfüllt - es ist keine Schnittstelle oder Delegat, es ist nicht nachweislich sicher, und der Typ ist nicht als sicher für die Varianz markiert. Also, keine Abweichung für Wörterbücher.

IEnumerable<T> erfüllt dagegen alle diese Bedingungen. Sie können IEnumerable<string> in IEnumerable<object> in C # 4 konvertieren.

Wenn das Thema der Varianz Sie interessiert, sollten Sie meine zwei Dutzend Artikel zu diesem Thema lesen:

Ссылка

    
Eric Lippert 19.12.2011, 20:45
quelle
4

Forschung Kontravarianz und Kovarianz. Für ein bestimmtes Beispiel, warum solch ein Fall eine schlechte Sache sein könnte, überprüfen Sie diese Antwort von Jon Skeet .

    
drharris 19.12.2011 20:40
quelle
2

Denken Sie darüber nach, was passieren würde, wenn es erlaubt wäre und Sie dann:

%Vor%

Das ist absolut erlaubt; HashSet<string> implementiert IEnumerable<string> und kann als Wert zu einem Dictionary<int, IEnumerable<string>> hinzugefügt werden. Es kann jedoch nicht zu einem Dictionary<int, List<string>> hinzugefügt werden, was das Objekt wirklich ist.

Wenn Sie es als schreibgeschützten IDictionary<int, IEnumerable<string>> verwenden möchten, können Sie eine gute Effizienz von einer Wrapper-Klasse erhalten, die in IEnumerable<string> umgewandelt wird.

Andernfalls müssen Sie die Werte in ein neues Dictionary<int, IEnumerable<string>> kopieren.

    
Jon Hanna 19.12.2011 20:43
quelle