如何创建实现 IDictionary<'K, 'V> 和 IEnumerable<'V> 的类型

2023-12-29

我想创建一个实现 IDictionary 和 IEnumerable 的只读键控集合。采用明显的方法我得到以下错误:

This type implements or inherits the same interface at different generic instantiations 'IEnumerable<'V>' and 'IEnumerable<KeyValuePair<'K,'V>>'. This is not permitted in this version of F#.

有没有不同的方法来实现这一目标?

EDIT- 由于这似乎是 F# 无法克服的限制,那么实现此目标的惯用方法是什么?我想到的一种想法是提供返回所需数据视图的成员,例如成员 x.List : IList 和成员 x.Dict : IDictionary。对象表达式可用于提供实现。还有其他想法吗?


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

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

正如 kvb 提到的,将实现公开为模块中的函数也是一个不错的选择 - 我认为许多标准 F# 库类型实际上都执行这两个选项(以便用户可以选择他/她喜欢的样式)。可以这样添加:

module MyCollection = 
  let toDict (a:MyCollection<_, _>) = a.Dictionary
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建实现 IDictionary<'K, 'V> 和 IEnumerable<'V> 的类型 的相关文章

随机推荐