26

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

运算符的默认实现==按引用比较对象。因此,当您覆盖 Equals (默认行为相同)时,您还必须指定==and!=运算符,以便它们调用 Equals (并使其在每个层次结构类中,因为==and!=运算符不是虚拟的)。

我的问题是为什么会这样?为什么要通过引用而不是使用 Equals 来比较对象==!=我想这样一个基本的事情应该是有原因的。

更新。

评论:我假设==应该依赖于 Equals(但反之亦然),因为您可以在基类中覆盖 Equals 并在派生类中自动使用此实现。==如果 Equals在其实现中使用它就行不通,因为==它不是虚拟的。

4

6 回答 6

9

我相信主要原因是==静态运算符,可以在需要实例null时调用对象。Equals

例如:

Foo foo1 = null;
Foo foo2 = null;

Console.WriteLine(foo1 == foo2); // cannot use Equals
于 2012-04-11T16:17:05.250 回答
5

Object.ReferenceEquals 是static比较引用相等性的成员。甚至值类型在传递给该方法之前也会被装箱。

怎么样Equals,它是一种virtual方法,这意味着它允许消费者覆盖功能。

因此,行为的默认实现==假定默认比较(参考)对您来说是可以的,如果您需要特定的东西,在这种情况下,框架为您提供了一个可以被覆盖的virtual方法。

于 2012-04-11T16:16:29.027 回答
2

“原因”是因为有时需要知道 A是否与B 相同,而不是它们是否仅仅是彼此“相等”。

例如,两个对象彼此相等可能对您的大多数业务逻辑有意义,但是,您可能还需要利用一些并发实用程序来执行原子操作,其中结果取决于对象身份,而不是相等性。

于 2012-04-11T16:37:12.407 回答
1

== 自 C 以来一直存在并用作参考,它已集成到语言语法中,而不必回复方法调用(即使两者的结果相同)。

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

于 2012-04-11T16:31:19.190 回答
0

在 Java 中,有时可以通过简单地比较引用来快速确定两个标识符是否相等。==有它的位置。如果你看一个IDE生成的equals方法,你经常会发现第一个比较是引用相等,毕竟,如果对象引用相同,为什么还要检查字段呢?

于 2012-04-11T16:42:04.857 回答
0

我将其称为功能。通过引用,两个相同的对象仍然是两个独立的对象。如果您覆盖 Equals,那么您可以确定两个对象是否相同。即使两个对象是相同的,我也可能想测试它们是否是同一个对象。我经常有理由覆盖 equals 但从来不需要覆盖 == != (但该语言提供了该选项)。

使用字符串他们会覆盖 == 而我不喜欢它。尽管字符串是一种引用类型,但相等运算符(== 和 !=)被定义为比较字符串对象的值,而不是引用(7.9.7 字符串相等运算符)。这使得对字符串相等性的测试更加直观。请参阅此介绍的问题。 WPF ListBox 滚动到底部

于 2012-04-11T17:12:52.847 回答