interface - 在类型定义之外实现相等

标签 interface f# operator-overloading equality

我有几种实现接口(interface)的类型。这些类型的相等性仅取决于接口(interface)成员。是否可以为这些类型定义一次相等性,而不覆盖每种类型的 Equalsop_Equality

编辑

我尝试了以下方法,但是,无论出于何种原因,它都会覆盖 = 的每次使用,即使对于未实现 IEntity 的类型也是如此。

[<AutoOpen>]
module Equality =
    let inline op_Equality (left:IEntity) (right:IEntity) = true

我还尝试使用灵活类型 (#IEntity)。结果相同。

最佳答案

您想要做的事情是混合或类型类可能在其他语言中启用的;不幸的是,F# 中没有等效的功能。您最好的选择可能是以下选项之一:

  1. 使用抽象基类而不是接口(interface)。
  2. 在类型之外编写相等方法,然后让所有实现都遵循它。例如,

    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),他们不会被迫使用您的相等方法 - 这是选择加入。

  3. 创建另一个用于 IEntity 相等性测试的运算符:

    let (==) (i1:IEntity) (i2:IEntity) =
      i1.Member1 = i2.Member1 &&
      ...
    

    这样做的(巨大)缺点是,包含 IEntity 的类型(例如元组、记录等)的结构相等不会使用此运算符来比较这些组件,这很可能导致令人惊讶的损坏代码。

关于interface - 在类型定义之外实现相等,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5266723/

相关文章:

java - 自动实现接口(interface)时参数从哪里来?

c - 在 C 中隐藏类型定义

java - 在 Strategy 设计模式中使用抽象类代替接口(interface)

optimization - 如何在 F# 中优化此代码以提高速度,以及为什么一个部分执行两次?

来自流阅读器的 F# 懒惰评估?

Python 对于 __iter__ 的定义实现抛出 TypeError

c++ - 定义适当的减法运算符

使用接口(interface)的泛型进行 C# 转换

f# - 我怎样才能做一个简单的elmish路由器?

c++ - 平等的定义