为什么默认 == 实现不调用等于

本文关键字:调用 实现 默认 为什么 | 更新日期: 2023-09-27 18:30:50

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

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

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

更新。

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

为什么默认 == 实现不调用等于

我相信

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

例如:

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

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

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

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

"原因是因为有时人们需要知道 A 是否与 B 相同而不是它们是否只是彼此"相等"。

例如,两个对象彼此相等

可能对大多数业务逻辑有意义,但是,您可能还需要使用一些并发实用程序,这些实用程序执行原子操作,其中结果依赖于对象标识,而不是相等。

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

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

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

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

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