2013-07-07 49 views
2

我定义我自己的类为什么我应该使用CustomEqualityAttribute来标记我的类型?

type public Observation(?values) = 
    ... 

它覆盖Object.Equals

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

,并进一步采写它采用了全球运营商=<>单元测试。我已验证我的覆盖的Equals确实被调用。

那么用[<CustomEqualityAttribute>]来标记我的班级有什么意义呢?如果我没有添加这个属性,我是否会为以后的一个讨厌的bug设置自己?不幸的是,这个属性上的documentation并不多说。

+0

[CustomEquality和CustomComparison]的值可能重复(http:// stackoverflow。com/questions/16594719 /定量与定制价值比较) –

回答

4

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

要确认你为什么需要[<CustomEqualityAttribute>],我看着它在规范,其中规定

CustomEquality

§类型必须有一个明确的实施覆盖 的Equals的(OBJ:OBJ)

+0

我都是引用规范,但规范如此简洁的事实似乎乞求IMO的问题 - 两者的优点是什么?压倒Equals并要求Equals被覆盖超过Equals? – ildjarn

2

[<CustomEquality>]属性存在的理由来自于情况下,你MUST使用它,而不是像你的那种,你在那里可能。前者的一个非常简单的例子是

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>]去型号声明
  • 或选择有自定义等于,当你必须以EqualsGetHashCode成员明确压倒一切的一起加入[<CustomEquality; NoComparison>]的类型声明,和/或System.IEquatable<_>System.Collections.IStructuralEquatable实施

你可以找到的F#平等和比较约束在this Don Syme's blog post扩展解释。

相关问题