【发布时间】:2018-11-14 15:33:47
【问题描述】:
我正在为键值存储样式 API 的变体进行抽象,其中我有以下接口(为清晰起见而简化)。
type IValue =
abstract member Id: int64
type IKey<'value when 'value :> IValue> = interface end
type IKeyGenerator<'value, 'key when 'value :> IValue and 'key :> IKey<'value>> =
abstract member Generate: 'value -> 'key
type IKeyValueStore<'value when 'value :> IValue> =
abstract member Store: 'value -> unit
abstract member Get: int64 -> 'value option
abstract member Find<'key when 'key :> IKey<'value>> : 'key -> 'value option
基本上每个值都可以通过多个key来查找,每个值的key都是由IKeyGenerators生成的。当我在IKeyValueStore 上调用Store 时,我想找到给定值的所有键生成器,运行它们中的每一个,并存储该值的每个键,以便随后可以通过这些键中的任何一个检索它。
我的问题是,虽然我可以反思地发现 IKeyGenerator 的所有实现,这些实现具有与此 IKeyValueStore 的 'value 类型匹配的 'value 类型参数,但我无法安全地将它们拆箱到一致类型。我尝试将它们全部拆箱到IKeyGenerator<'value, IKey<'value>>,但如果具体实现没有以这种方式显式实现接口,这将不起作用。如果他们实现的接口引用了IKey 的特定实现,则拆箱失败。
然后我尝试引入一个简化的IKeyGenerator<'value> 接口,该接口将Generate 方法定义为简单地返回IKey<'value> 而不是'key :> IKey<'value>,这解决了取消装箱所有实现的问题,但随后我在下游遇到了问题不知道键的实际类型(例如,当该值有多个可能的键时,为了执行Find)。
如果它们都为相同类型的值实现IKey<'value>,是否有某种方法可以安全地获取不同IKey 实现的IKeyGenerator 实例列表?
【问题讨论】: