F# 如何为受歧视的并集重写.Equals()?
我有一个区分的联合类型,希望覆盖F# 如何为受歧视的并集重写.Equals()?,f#,overriding,equality,discriminated-union,F#,Overriding,Equality,Discriminated Union,我有一个区分的联合类型,希望覆盖.Equals() 在这个简单的例子中,我可以使用int的.Equals函数来解决这个问题,但在我的代码中,otherStuff不支持结构比较 以下代码是我的最佳尝试: [<CustomEquality>] type ModelArg = { Name: string; OtherStuff: int} with override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Na
.Equals()
在这个简单的例子中,我可以使用int
的.Equals函数来解决这个问题,但在我的代码中,otherStuff不支持结构比较
以下代码是我的最佳尝试:
[<CustomEquality>]
type ModelArg = { Name: string; OtherStuff: int}
with override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Name
我希望避免这样做,因为我实际上只关心字段Name
,而且出于性能原因
当然,我可以编写一个equals
函数,但是我不能将它与List
函数一起使用,比如List.contains
,我需要这样做
有什么建议吗?错误告诉您,因为您正在重写
Equals
方法,所以重写GetHashCode
也是一个非常好的主意
这是因为在.NET中(不仅仅在F#中),哈希代码通常被用作等式的近似值。例如,如果要将对象放在哈希表中,哈希表将基于GetHashCode
在各个存储桶之间分配对象,并以这种方式在存储桶中查找对象。然后,如果Equals
的实现方式不同于GetHashCode
,则哈希表的行为将不可预测-它可能无法查找刚刚插入的对象或类似的对象
此外,错误消息并不建议您将int包含在相等的定义中。它所说的就是您需要实现GetHashCode
,并以与等于
实现相同的意义来实现它。只要您从未真正调用GetHashCode
,这样做也不会对性能造成影响。如果你这样做了,请看上面
由于Equals
实现所做的只是比较Name
字段,因此将GetHashCode
委托给同一字段可能也是有意义的:
[<CustomEquality>]
type ModelArg = { Name: string; OtherStuff: int}
with
override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Name
override this.GetHashCode() = this.Name.GetHashCode()
谢谢我试过了,但得到了一个信息:“必须将
CustomEquality
属性与NoComparison
或CustomComparison
属性结合使用。我加上了前者,一切都很好。我还修改了您关于处理参数为另一种类型的情况的建议:在这种情况下,我生成了一个异常。它看起来像一个记录类型,而不是一个有区别的联合。我错过什么了吗?
[<CustomEquality>]
type ModelArg = { Name: string; OtherStuff: int}
with
override this.Equals (o: obj) = this.Name = (o :?> ModelArg).Name
override this.GetHashCode() = this.Name.GetHashCode()
override this.Equals (o: obj) =
match o with
| :? ModelArg as ma -> this.Name = ma.Name
| _ -> false