2016-05-16 10 views
0

Für IDictionary<TKey, TValue> sind die Keys und Values Eigenschaften vom Typ ICollection<TKey> und ICollection<TValue>.Datentyp der Schlüssel und Werte von IReadOnlyDictionary

Für IReadonlyDictionary<TKey, TValue> die Keys und Values Eigenschaften sind vom Typ IEnumerable<TKey> und IEnumerable<Value>.

Warum sind nicht die Eigenschaften von nur die entsprechenden ReadOnly-Schnittstellen, nämlich IReadOnlyCollection<TKey> und IReadOnlyCollection<TValue>?

Man könnte sich wundern, warum beide Eigenschaften nicht vom Typ IEnumerable sind, da Sie das Wörterbuch nicht durch die zwei Eigenschaften, sondern durch Add und Remove Methoden ändern können. In der Tat die ICollection zurückgegeben von IDictionary.Keys hat die IsReadOnly Eigenschaft festgelegt, so versucht, Add oder 10 auf die Eigenschaft zu rufen wirft eine NotSupportedException mit der zusätzlichen Informationen Muting eine Schlüsselsammlung aus einem Wörterbuch abgeleitet ist nicht erlaubt.

Wenn man das Wörterbuch sowieso nicht über seine Eigenschaften ändern kann, warum sind die beiden IReadOnlyCollections nicht? Die Schnittstellen wurde zuerst in .NET 4.5 eingeführt, also denke ich, dass das nicht ohne einen unerwünschten Bruch der Abwärtskompatibilität getan werden kann.

Antwort

1

Es stellt eine geringere Belastung für Leute dar, die eine benutzerdefinierte IReadonlyDictionary<TKey, TValue> implementieren, wenn sie keine Dinge verwenden wollten, die von IReadOnlyCollection für ihre Backing Stores abgeleitet sind.

Wenn Sie die integrierte Implementierung von ReadOnlyDictionary verwenden, gibt es nichts, was Sie daran hindert, die Schnittstelle zu implementieren.

IReadOnlyDictionary<Foo, Bar> baz = GetDictionary(); 

IEnumerable<Foo> keys = baz.Keys; 
IReadOnlyCollection<Foo> keysCollection = keys as IReadOnlyCollection<Foo>; 

if(keysCollection != null) 
{ 
    //This code will execute for the built in implmentation of `ReadOnlyDictionary<Foo, Bar>` 
} 
+0

Dies ist ein bisschen stumpf. Willst du damit sagen, dass es einfacher, gebräuchlicher und verständlicher ist, eine Keys-Sammlung oder eine Values-Sammlung zu erstellen, die aufzählbar ist, ohne "ICollection " in "IEnumerable " oder "IEnumerable" umwandeln zu müssen? Weil ich damit einsteigen konnte. –

+0

Ich bin nicht 100% sicher, was Sie sagen, aber ich denke, ich stimme zu ... –

+0

'ICollection ' erbt von beiden 'IEnumerable 'und' IEnumerable'. Die Entwickler der neueren 'IReadOnlyCollection' fühlten offensichtlich, dass sie die zusammengesetzte Schnittstelle nicht mehr benötigten und konnten direkt von'IEnumerable ' und 'IEnumerable' erben. –

1

Sie können entweder die Sammlung von Schlüsseln oder die Sammlung von Werten durch die Keys und Values Eigenschaften ändern. Sie verwenden diese Eigenschaften nur, um auf die Schlüssel und Werte zuzugreifen. Es spielt also keine Rolle, ob es sich um schreibgeschützte Sammlungen handelt oder nicht.

Die Schlüssel und Werte können nur durch Hinzufügen von Elementen zum Wörterbuch geändert werden, was mit einem IReadOnlyDictionary nicht möglich ist.

Durch die Verwendung einer ICollection wird außerdem eine zusätzliche Einschränkung dahingehend festgelegt, wie eine bestimmte Implementierung von IReadOnlyDictionary diese Eigenschaften zurückgibt. Ein IEnumerable<T> kann auf viele andere Arten implementiert werden, sogar durch eine Methode, die eine yield-Anweisung verwendet. Wenn der zurückgegebene Typ lautet, wird das Wörterbuch gezwungen, etwas aufzufüllen, das ICollection<T> implementiert. Es könnte immer noch das tun, aber wenn etwas implementiert , dann implementiert es auch IEnumerable<T>.

Also würde ich mich anders fragen - warum gibt IDictionary<T>ICollection<T> für diese Eigenschaften anstelle von IEnumerable<T> zurück. (Es könnte ein guter Grund sein. Aber jetzt frage ich mich.)

0

IEnumerable<T> können Sie Vorteil Linq Methoden und die gesamte Iterator Infrastruktur zu übernehmen direkt, ohne eine Besetzung durchführen zu müssen.

Sie können die Daten in der zugrunde liegenden Implementierung ReadOnlyDictionary sowieso nicht ändern, auch nicht durch die Key und Value Sammlungen. IEnumerable<T> ist es egal, ob die zugrunde liegende Implementierung schreibgeschützt ist oder nicht.

+0

Wie 'IReadOnlyCollection ' implementiert 'IEnumerable ' sollte es, meines Wissens, in der Lage sein, die gleichen Linq-Methoden zu verwenden? Beide dieser beiden Schnittstellen verbergen die Methoden 'Add()', 'Remove()' und 'Clear()', die 'ICollection' hat, was hier keinen Sinn ergibt, da die' Keys' und 'Values' Eigenschaften nur gelesen werden wie du auch sagst. Wenn 'Keys' oder' Values' nicht träge generiert werden können, scheint mir die Verwendung von 'IEnumerable ' nur eine unnötige Verallgemeinerung zu sein, die dazu führen könnte, dass die Eigenschaften * faul sein oder nicht bereits im Speicher sind . –

+0

Counter-Frage: Welche Vorteile würden durch die Verwendung von 'IReadOnlyCollection ' anstelle von 'IEnumerable 'für die Sammlung von Schlüssel und Wert entstehen? –

+0

Das kann ich darüber nachdenken, ob die zugrunde liegende Sammlung eifrig oder faul ist. –

Verwandte Themen