重写 Equals 方法时是不是需要重写 == 和 != 运算符? (。网)

Posted

技术标签:

【中文标题】重写 Equals 方法时是不是需要重写 == 和 != 运算符? (。网)【英文标题】:Is it necessary to override == and != operators when overriding the Equals method? (.NET)重写 Equals 方法时是否需要重写 == 和 != 运算符? (。网) 【发布时间】:2010-11-16 08:39:46 【问题描述】:

还是建议这样做? 为什么?

【问题讨论】:

【参考方案1】:

如果您重写了 equals 方法并且仍然希望能够检查是否相等(或不等式),那么您可能也应该重写 == 和 != 方法。

【讨论】:

【参考方案2】:

这不是必须的,而是明智的做法。

如果您正在创建一个框架并且其他开发人员不是您要使用该对象,您应该覆盖 == 和 !=。这样,当开发人员可以使用它时,他们至少有正确的逻辑来比较这 2 个对象,而不仅仅是在内存中相同。

我会确保您的 == & != 确实调用了您的 equals 方法。

【讨论】:

【参考方案3】:

见Guidelines for Implementing Equals and the Equality Operator (==)

对于值类型(结构)“在覆盖 Equals 方法的任何时候实现 ==”

对于引用类型(类),“大多数引用类型,即使是那些实现 Equals 方法的引用类型,也不应该覆盖 ==。”不可变类和具有类值语义的类除外。

【讨论】:

【参考方案4】:

这是可取的,因为如果出现以下情况会出乎意料:

if (foo == bar)

...与以下行为不同:

if (foo.Equals(bar))

【讨论】:

在很多情况下foo==bar 的行为与foo.Equals(bar) 不同。错误地相信它们的等价性往往比承认它们不能总是表现相同并且不应该被期望造成更大的麻烦[事实上,该框架在Equals的含义上有一些不一致之处,这源于恕我直言的错误愿望使其匹配==]。 @supercat 一个很好的例子是在比较可空类型时,Equals 很聪明,会检查每一侧的 HasValue。 @Gary:我想的更多是Decimal。如果没有一个排名高于另一个,则拥有一种将排名对象视为相等的比较方法很有用,但拥有一种可以将排名相同的对象(例如 1.0d 和 1.00d)识别为不同的相等测试方法也很有用。恕我直言,此类对象应与 ==.Equals 产生相反的比较结果。【参考方案5】:

没必要,你不这么做没人会杀你的。

但是,请注意,写 (A == B) 通常比写 A.Equals(B) 更自然。如果您同时提供这两种方法,您的代码的使用者会更容易。

【讨论】:

【参考方案6】:

请参阅guidelines for overriding Equals() and operator==。

引用:

默认情况下,运算符 == 通过确定两个引用是否指示同一个对象来测试引用是否相等。因此,引用类型不必实现 operator == 即可获得此功能。当类型是不可变的,即实例中包含的数据不能更改时,重载运算符 == 来比较值相等而不是引用相等可能很有用,因为作为不可变对象,它们可以被认为与 long 相同因为它们具有相同的价值。在非不可变类型中覆盖 operator == 不是一个好主意。

基本上:

如果您希望 == 和 != 表现得像 Equals(..)!Equals(..) 您需要实现运算符。您通常只对不可变类型执行此操作。

【讨论】:

【参考方案7】:

除了这里已经给出的所有答案,别忘了确保GetHashCode() 也是一致的。

【讨论】:

【参考方案8】:

在 A.Equals(B) 中 A 不能为空 在 A == B 中的任何一个都可以为空

【讨论】:

【参考方案9】:

重写 == 使其调用 Equals 让我觉得对于引用类型来说通常是个坏主意。如果您覆盖 == 以使其调用 Equals,那么我认为您的代码用户无法测试两个对象引用是否引用完全相同的对象(相对于具有相同属性的对象)。

如果人们想要测试您的类实例的值相等性,那么他们当然应该调用 Equals,而保存 == 专门用于测试引用相等性。

【讨论】:

您可以使用Object.ReferenceEquals 专门检查引用相等性。 虽然可以使用Object.ReferenceEquals,但它相当笨拙。我认为 C# 使用 == 标记作为可重载平等测试和引用平等测试运算符是该语言中最大的设计错误之一。

以上是关于重写 Equals 方法时是不是需要重写 == 和 != 运算符? (。网)的主要内容,如果未能解决你的问题,请参考以下文章

重写equals 方法的注意事项

JAVA中重写equals()方法的同时要重写hashcode()方法

为什么重写equals方法必须重写hashcode方法?

重写equals就必须重写hashCode的原理分析

为什么要重写equals和hashcode方法

半夜思考, 为什么建议重写 equals()方法时, 也要重写hashCode()方法