簡體   English   中英

為什么F#映射使用可變操作實現接口?

[英]Why does F# map implement the interfaces with mutable operations?

當我意識到F#的map實現IDictionary <'Key,'Value>和ICollection<KeyValuePair<'a, 'b>>考慮到作為合同一部分支持突變(添加和刪除)時,我感到有些驚訝。

map的實現時,它只是在您嘗試引起突變時的例外!

let map = [| (1, "one"); (2, "two") |] |> Map.ofArray
let dict = map :> IDictionary<int, string>
dict.Add(3, "three");;

上面的代碼拋出異常:

System.NotSupportedException:不能對映射值進行突變。 在Microsoft.FSharp.Collections.FSharpMap中2.System-Collections-Generic-IDictionary 2-Add(TKey k,TValue v)在。$ FSI_0007.main @()處由於錯誤而停止

正如預期的那樣。

對於一個不可變的集合來說,僅當該集合的使用者試圖引起突變時才拋出異常,才能夠將自己暴露為可變的,這似乎是一個危險的決定。

我在這里想念什么嗎?

我認為主要原因是.NET沒有任何表示不可變(一個接口的一部分)字典的接口。 這意味着所有.NET API即使僅打算從字典中讀取,也必須采用IDictionary<K, V>作為參數。 所以:

  • 實現IDictionary<'K, 'V>幾乎是使F#不變映射可用作需要需要支持對象的任何.NET庫的參數的唯一方法。 可悲的是,.NET中沒有只讀替代方法。

  • 對我來說,實現ICollection<KeyValuePair<'K, 'V>>並沒有太大意義,因為有一個只讀替代IEnumerable<KeyValuePair<'K, 'V>>並且不可變映射也實現了此接口。

    但是也許有些.NET庫采用ICollection<'T> (以提高效率-即在不枚舉所有元素的情況下獲取Count )並以只讀方式使用它。

    編輯:正如Daniel在評論中所指出的,實現ICollection是必需的,因為IDictionary接口繼承自它。

我認為很遺憾缺少只讀接口,但是可能無法解決此問題,因為這將意味着更改現有的.NET集合庫。

IsReadOnly允許接口為只讀,即使它提供了可寫的方法。

這是一個.Net的東西。 您不能只實現某些接口,而他們卻想實現IDictionary`2接口-因為您可以使用其查詢和轉換方法(因此您可以將其傳遞給從IDictionary`2讀取的函數)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM