F# 如何创建实现IDictionary的类型<';K、 &x27;V>;和IEnumerable<';V>;

F# 如何创建实现IDictionary的类型<';K、 &x27;V>;和IEnumerable<';V>;,f#,F#,我想创建一个只读键控集合,该集合实现IDictionary和IEnumerable,恐怕不行。CLR当然允许实现多个接口(即使是相同的基类型),但不支持F#语言。我相信如果你用C语言编写这个类,你不会有任何问题,但是F在当前版本中会给你带来问题。正如Noldorin所说,这是不可能的。一种惯用方法是在与您的类型同名的模块上提供toSeq和toDict函数(如List.toSeq、Array.toSeq等)。一种相对简单的方法是将两个接口的实现公开为您正在编写的类型的成员。这可以通过使用对象表达式

我想创建一个只读键控集合,该集合实现IDictionary和IEnumerable,恐怕不行。CLR当然允许实现多个接口(即使是相同的基类型),但不支持F#语言。我相信如果你用C语言编写这个类,你不会有任何问题,但是F在当前版本中会给你带来问题。

正如Noldorin所说,这是不可能的。一种惯用方法是在与您的类型同名的模块上提供
toSeq
toDict
函数(如
List.toSeq
Array.toSeq
等)。

一种相对简单的方法是将两个接口的实现公开为您正在编写的类型的成员。这可以通过使用对象表达式很好地完成,或者只需编写一段代码来构造某种类型并将其作为结果返回即可。第二种方法如下所示:

type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    Seq.zip keys values |> dict
  member x.Enumerable = 
    values |> List.toSeq
type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    { new IDictionary<'K, 'V> with 
        member d.Add(k, v) = ... }            
  member x.Enumerable = 
    // Similarly for IEnumerable
    values |> List.toSeq
module MyCollection = 
  let toDict (a:MyCollection<_, _>) = a.Dictionary
键入MyCollection,值:list dict
成员x.可枚举=
值|>List.toSeq
第一种方法(如果您想直接实现接口的方法)大致如下:

type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    Seq.zip keys values |> dict
  member x.Enumerable = 
    values |> List.toSeq
type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    { new IDictionary<'K, 'V> with 
        member d.Add(k, v) = ... }            
  member x.Enumerable = 
    // Similarly for IEnumerable
    values |> List.toSeq
module MyCollection = 
  let toDict (a:MyCollection<_, _>) = a.Dictionary
键入MyCollection,值:list list.toSeq
如kvb所述,将实现作为模块中的函数公开也是一个很好的选择-我认为许多标准的F#library类型实际上可以同时执行这两个选项(以便用户可以选择他/她喜欢的样式)。可以这样添加:

type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    Seq.zip keys values |> dict
  member x.Enumerable = 
    values |> List.toSeq
type MyCollection<'K, 'V when 'K : equality>(keys:list<'K>, values:list<'V>) = //'
  member x.Dictionary = 
    { new IDictionary<'K, 'V> with 
        member d.Add(k, v) = ... }            
  member x.Enumerable = 
    // Similarly for IEnumerable
    values |> List.toSeq
module MyCollection = 
  let toDict (a:MyCollection<_, _>) = a.Dictionary
模块MyCollection=
让我们来读一本字典