2

我已经定义了自己的班级

type public Observation(?values) = 
    ...

覆盖Object.Equals

    override o1.Equals o2 = 
        let isEqual = ...
        isEqual

=并进一步编写了一个使用全局运算符和的单元测试<>。我已经验证了我的覆盖Equals确实被调用了。

那么用 标记我的班级有什么意义[<CustomEqualityAttribute>]呢?如果我不添加该属性,我会在以后为自己设置一个讨厌的错误吗?不幸的是,关于这个属性的文档并没有说太多。

4

2 回答 2

4

一个原因可能是添加[<CustomEqualityAttribute>]迫使您覆盖Object.Equals. 如果没有该属性,删除该Equals方法会更改运行时行为,而添加该属性会强制执行相等方法,如果缺少该属性会导致编译错误。

为了确认您需要的原因[<CustomEqualityAttribute>],我在规范中查找了它,其中指出

自定义平等

§ 类型必须有一个显式的重写 Equals(obj: obj)

于 2013-07-07T05:22:43.500 回答
2

属性存在的理由[<CustomEquality>]来自您必须使用它的情况,而不是来自您可能使用的情况。前者的一个非常简单的例子是

type Strange = Behavior of (int -> int)

let a = Behavior (fun x -> x + 1)
let b = Behavior (fun x -> x + 1)

a = b
b = b

编译器会拒绝任何尝试使用=,因为匿名函数元素Strange根本不支持任何等式约束。

关于Strange类型值相等的选项是:

  • 要么永远不要检查Strange类型值是否相等,也不需要为此默认选择使用任何属性
  • 或通过添加到类型声明来选择具有引用相等性[<ReferenceEquality>]
  • 或选择自定义相等,当您必须添加[<CustomEquality; NoComparison>]类型声明以及显式覆盖Equals andGetHashCode成员和/或实现System.IEquatable<_>orSystem.Collections.IStructuralEquatable

您可以在此 Don Syme 的博客文章中找到有关 F# 相等和比较约束的扩展说明。

于 2013-07-07T13:46:48.757 回答