我有几种实现接口(interface)的类型。这些类型的相等性仅取决于接口(interface)成员。是否可以为这些类型定义一次相等性,而不覆盖每种类型的 Equals
或 op_Equality
?
编辑
我尝试了以下方法,但是,无论出于何种原因,它都会覆盖 =
的每次使用,即使对于未实现 IEntity
的类型也是如此。
[<AutoOpen>]
module Equality =
let inline op_Equality (left:IEntity) (right:IEntity) = true
我还尝试使用灵活类型 (#IEntity
)。结果相同。
最佳答案
您想要做的事情是混合或类型类可能在其他语言中启用的;不幸的是,F# 中没有等效的功能。您最好的选择可能是以下选项之一:
- 使用抽象基类而不是接口(interface)。
在类型之外编写相等方法,然后让所有实现都遵循它。例如,
let entityEquals (i1:IEntity) (i2:IEntity) = i1.Member1 = i2.Member1 && i1.Member2 = i2.Member2 && ... type MyEntity() = interface IEntity with member x.Member1 = ... ... override x.Equals(y) = match y with | :? IEntity as y -> entityEquals x y | _ -> false override x.GetHashCode() = ...
除了一些样板文件之外,这里的缺点是,如果其他人实现了您的
IEntity
接口(interface),他们不会被迫使用您的相等方法 - 这是选择加入。创建另一个用于
IEntity
相等性测试的运算符:let (==) (i1:IEntity) (i2:IEntity) = i1.Member1 = i2.Member1 && ...
这样做的(巨大)缺点是,包含 IEntity 的类型(例如元组、记录等)的结构相等不会使用此运算符来比较这些组件,这很可能导致令人惊讶的损坏代码。
关于interface - 在类型定义之外实现相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5266723/