为什么要使用自定义质量属性标记我的类型?

时间:2013-07-07 05:09:07

标签: .net f#

我已经定义了自己的班级

type public Observation(?values) = 
    ...

覆盖Object.Equals

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

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

那么用[<CustomEqualityAttribute>]标记我的课程的重点是什么?如果我不添加该属性,我是否会为自己制作一个讨厌的bug?不幸的是,此属性上的documentation并没有太多说明。

2 个答案:

答案 0 :(得分:4)

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

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

  

CustomEquality

     

§类型必须具有覆盖的显式实现   等于(obj:obj)

答案 1 :(得分:2)

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

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>]添加到类型声明以及明确覆盖EqualsGetHashCode成员时,
  • 或选择具有自定义相等,以及/或实施System.IEquatable<_>System.Collections.IStructuralEquatable

您可以在this Don Syme's blog post中找到F#相等和比较约束的扩展说明。