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