Warum implementiert F # map die Schnittstellen mit änderbaren Operationen?

8

Ich war etwas überrascht, als ich feststellte, dass F # 's map sowohl IDictionary & lt; Key, Value & gt; und ICollection<KeyValuePair<'a, 'b>> , wenn man bedenkt, dass beide Mutationen (Hinzufügen und Entfernen) als Teil des Vertrags unterstützen.

Wenn Sie sich die Implementierung von map ansehen, wird dies einfach ausgeschlossen, wenn Sie versuchen, Mutationen zu verursachen !

%Vor%

Der obige Code löst die Ausnahme aus:

  

System.NotSupportedException: Map-Werte können nicht mutiert werden. beim   Microsoft.FSharp.Collections.FSharpMap 2.System-Collections-Generic-IDictionary 2-Add (TKey   k, TValue v) at. $ FSI_0007.main @ () Gestoppt   aufgrund eines Fehlers

was wie erwartet ist.

Damit eine unveränderbare Sammlung sich selbst als veränderlich entlarven kann, nur um eine Ausnahme auszulösen, wenn der Konsument dieser Sammlung versucht, eine Mutation zu verursachen, scheint dies eine gefährliche Entscheidung zu sein.

Fehle ich hier etwas?

    
theburningmonk 20.06.2012, 13:03
quelle

3 Antworten

6

IsReadOnly ermöglicht, dass die Schnittstelle schreibgeschützt ist, obwohl beschreibbare Methoden zur Verfügung stehen.

    
Guvante 20.06.2012, 15:39
quelle
9

Ich denke, der Hauptgrund ist, dass .NET keine Schnittstelle hat, die unveränderlich (Teil einer Schnittstelle eines) Wörterbuchs darstellt. Dies bedeutet, dass alle .NET-APIs IDictionary<K, V> als Parameter verwenden müssen, auch wenn sie nur aus dem Wörterbuch lesen wollen. Also:

  • Das Implementieren von IDictionary<'K, 'V> ist praktisch die einzige Möglichkeit, die unveränderliche F # -Map als Parameter für alle .NET-Bibliotheken nutzbar zu machen, die ein Objekt benötigen, das die Suche unterstützt. Leider gibt es in .NET keine schreibgeschützte Alternative.

  • Das Implementieren von ICollection<KeyValuePair<'K, 'V>> macht mir nicht viel Sinn, weil es eine schreibgeschützte Alternative gibt, die auch diese Schnittstelle implementiert.

    Aber vielleicht gibt es einige .NET-Bibliotheken, die IEnumerable<KeyValuePair<'K, 'V>> (für die Effizienz - d. h. um ICollection<'T> ohne Aufzählung aller Elemente zu erhalten) verwenden und sie nur lesend verwenden.

    BEARBEITEN: Wie von Daniel im Kommentar erwähnt, ist die Implementierung von Count erforderlich, weil die Schnittstelle ICollection von ihr erbt.

Ich denke, das Fehlen einer schreibgeschützten Schnittstelle ist ziemlich bedauerlich, aber es gibt wahrscheinlich keine Möglichkeit, dies zu beheben, da dies bedeuten würde, die vorhandenen .NET-Auflistungsbibliotheken zu ändern.

    
Tomas Petricek 20.06.2012 13:59
quelle
4

Es ist eine .Net-Sache. Sie können nicht nur einen Teil der Schnittstelle implementieren, und dennoch wollten sie die IDictionary'2 -Schnittstelle implementieren - weil Sie ihre Abfrage- und Konvertierungsmethoden verwenden können (so können Sie sie an Funktionen übergeben, die von IDictionary'2 lesen).

    
Ramon Snir 20.06.2012 13:18
quelle

Tags und Links