C# 关于 Equals 实现的不同 MSDN 指南

本文关键字:MSDN 指南 关于 Equals 实现 | 更新日期: 2023-09-27 18:34:22

为什么以下文档在实现该方法时讨论不同的方法Equals

  • [MSDN] 重写 equals() 和运算符的准则 ==(C# 编程指南)
  • [MSDN]实现等于方法

第二个文档(较新的文档)没有显式实现Equals的强类型版本(如public bool Equals(MySuperTrooperClass o))。

从其中一个准则中删除强类型方法的根本原因是什么,我应该在生产代码中使用哪种方法?

C# 关于 Equals 实现的不同 MSDN 指南

删除强类型版本没有任何好处。恰恰相反,正如第一页本身所提到的

还建议除了实施平等之外 (对象),任何类也为自己的类型实现 Equals (类型), 以增强性能。

对于值类型,情况更是如此。

我假设第二页根本不关心这一点,因为只有弱类型版本在System.Object上定义。强类型版本通常与实现IEquatable<T>齐头并进,其文档提到了Equals(T)Equals(object)之间的交互。

Microsoft决定在许多基元类型中重载Equals的一个不幸的副作用是,在许多情况下,即使((Object)X).Equals(Y)将表现为等价关系(它应该),但由于隐式转换,X.Equals(Y)不会。 例如,3.Equals(3.0)将返回 false,但(3.0).Equals(3)将返回 true。 虽然==运算符并不那么糟糕(通常如果X==YY==X),但它仍然没有指定等价关系(例如,如果X = Int64.MaxValue,Y=X-1和Z=(Double)X,则X==Z和Y==Z,但X!=Y)。

也许Microsoft放弃了关于提供与Equals(Object)行为相同的Equals()重载的建议的原因是,虽然隐式强制转换可能使前者无法表现为等价关系,但后者应该表现为等价关系,没有例外。

应实现强类型的 Equals 以提高性能。正如第一篇文章中所写的那样

当你想检查两个东西是否具有相同的值时,你使用 ==
当您想检查两件事是否实际上引用到同一个实例时,请使用 Equals()。

请记住,只有当 Equals() 为真时,== 也必须为真。

关于 GetHashCode() - 在某些情况下包含字典等结构,请使用此特定方法来区分数据。由您决定如何区分数据,但是当对象的值被更改以正常工作时,不得更改 GetHashCode()。这意味着它应该在对象生命周期内保持相同的值。

当你做这样的事情时:

MyClass A = new MyClass();
MyClass B = A;

当您检查 (A==B) 时,您实际上检查指针 A 地址是否与指针 B 地址具有相同的值。
因此,您不需要在 99.99% 的共同开发中实现 Equals()。