为什么默认情况下的“==”实现不调用Equals方法?

26

可能是重复问题:
为什么 ReferenceEquals 和 == 运算符与 Equals 的行为不同

== 运算符的默认实现通过引用比较对象。因此,当你重写 Equals(其默认行为相同)时,你也必须指定 ==!= 运算符,使它们调用 Equals(并把它放在层次结构中的每个类中,因为 ==!= 运算符不是虚拟的)。

我的问题是为什么会这样?为什么 ==!= 比较对象时使用引用而不是使用 Equals?我想这应该有一个根本原因。

更新:

关于评论:我假设 == 应该依赖于 Equals(但反之则不然),因为你可以在基类中重写 Equals 并在派生类中自动使用该实现。如果 Equals 在其实现中使用了 ==,那就行不通了,因为 == 不是虚拟的。


1
按设计来说,跟Java很相似。 - James Michael Hare
2
@JamesMichaelHare,设计决策并非凭空而来... - SiberianGuy
1
==的两侧都为null时,它应该做什么? - thecoop
同意,我只是在说可能是因为Java有==作为引用相等性,而Equals()可以被重写以提供等价性的原因。 - James Michael Hare
@JamesMichaelHare,好的,我会在问题中添加Java标签。 - SiberianGuy
6个回答

10

我认为主要原因是==是一个静态运算符,可以在null对象上调用,而Equals需要实例

例如:

Foo foo1 = null;
Foo foo2 = null;

Console.WriteLine(foo1 == foo2); // cannot use Equals

1
但是Object.ReferenceEquals也是一个静态方法。 - SiberianGuy

5

Object.ReferenceEquals是一个静态成员,用于比较引用的相等性。即使是值类型,在传递给该方法之前也会进行装箱。

那么Equals呢?它是一个虚方法,这意味着它允许消费者重写功能。

因此,默认的==行为实现假定默认比较(引用)对您而言是可以的,如果需要特定的内容,则框架为您提供了一个可以重写的虚方法。


1
所以默认的比较(引用)对我来说不好,我重写了Equals但为什么我必须指定==和!=?当我重写Equals但仍需要通过引用比较时,有什么用例需要使用==和!=? - SiberianGuy
@Idsa:如果你这样做,那就是一条通往混乱的真正之路: )。在指定类型中,必须有一种比较方式。我认为这是框架设计者的原始想法。“定义一种比较对象的方法,并且它必须是唯一可能的方式,以避免歧义”。 - Tigran

2

"原因"是因为有时候需要知道A是否与B是同一实例,而不仅仅是它们是否相互“相等”。

例如,两个对象相互相等可能对大多数业务逻辑都有意义,但您可能还需要使用一些并发工具,其中结果取决于对象标识而不是相等性。


2
但是对于这种情况,有Object.ReferenceEquals可用。 - SiberianGuy
2
不是Java...这也是此问题的标签。 - Tim Bender
1
所以真正的问题是,既然C#设计者在设计C#语言之前已经有了十年实践Java的经验和知识,为什么他们还要这么做。我猜可能是为了保持一致性。 - Tim Bender
不幸的是,C# 在引用相等测试运算符和可重载相等测试运算符中使用了相同的标记;很多代码都是在假设foo == bar等同于Object.ReferenceEquals(foo, bar)的情况下编写的,但这种假设并不总是成立。 - supercat

1

自从C语言开始,"=="就一直被用作引用,它已经被整合到语言语法中,而不是依赖于方法调用(即使两者的结果相同)。

简单来说,因为C#不是Objective C :)


0
在Java中,有时候通过比较引用来快速确定两个标识符是否相等是很方便的。 == 有其作用。如果你查看一个IDE生成的equals方法,你会经常发现第一个比较是引用相等性,毕竟,如果对象引用相同,为什么要检查字段呢?

0

我会称之为一个特性。通过引用,两个相同的对象仍然是两个独立的对象。如果你重写Equals方法,那么你可以确定两个对象是否相同。即使两个对象是相同的,我也可能想测试它们是否是同一个对象。我经常有理由重写equals方法,但从未有过需要重写==和!=(但该语言提供了这个选项)。

对于字符串,它们重写了==,我不喜欢这样。虽然字符串是引用类型,但等式运算符(==和!=)被定义为比较字符串对象的值,而不是引用(7.9.7字符串等式运算符)。这使得测试字符串相等更加直观。看看这引入的问题。WPF ListBox Scroll to the bottom


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接