为什么默认 == 实现不调用等于
本文关键字:调用 实现 默认 为什么 | 更新日期: 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 列表框 滚动到底部