2009-10-02 57 views
7

我明白为我的对象显式实现Equals和GetHashCode。C#显式平等运算符实现必要

但我不知道,如果它使任何意义,也明确落实==和=操作是这样的:!

public static bool operator ==(Salutation left, Salutation right) 
{ 
    return Equals(left, right); 
} 

不C#不会自动使用Equals方法被调用时==?

回答

8

确实有意义,覆盖相等运算符以及Equals。这实际上是非常明智的。

微软在MSDN上发布了官方Guidelines for Implementing Equals and the Equality Operator (==)。我肯定会按照推荐的做法去那里。这两个要点是:

  • 实现无论何时实施的Equals 方法GetHashCode方法。这将保持Equals和 GetHashCode同步。
  • 每当您实现相等运算符 (==)时重写Equals方法,并使它们执行相同的操作。 这使基础设施代码(如 )成为Hashtable和ArrayList,使用Equals方法的 与使用 等号运算符编写的用户代码具有相同的行为方式 。

乔恩斯基特也写了useful MSDN blog post这个话题,总结如何Equals,默认情况下对参考/值类型==操作员的工作量。

最重要的部分引用如下:

equals方法只是一个虚拟 一个在System.Object的定义,并通过 为准类选择 重写这样做。 ==运算符是一个 运算符,它可以通过 类过载,但通常具有 标识行为。

对于在==没有 被重载引用类型,比较 两个引用是否指向同一个对象 - 这也正是 实施的Equals的确实在 System.Object的。

默认情况下,值类型不会为==提供过载 。但是,大多数 框架提供的值类型都提供它们自己的过载。 一个值类型等于 的默认实现由 值类型提供,并使用反射来使 比较,这使得它 比 类型特定的实施显著较慢通常 会。这个实现也调用 在两个值内的参考对之间进行比较。

+0

谢谢。我接受了你的回答,但是你能否在Joel所说的一些事情上编辑? ==如果没有被覆盖,它的行为如何。 – Tigraine 2009-10-02 21:30:29

+0

@Tigraine:没问题。事实上Joel所说的(以及更多)是在Jon Skeet所写的页面中提到的。如果你喜欢,我会引用。 – Noldorin 2009-10-02 21:40:21

+0

谢谢.. :) 这只是更容易阅读这种方式;) – Tigraine 2009-10-03 19:02:23

2

如果你不重载它,==只是检查引用相等:双方是否指向同一个对象?

如果您需要值相等(两侧的不同对象具有相同的值?),则可以重载操作符。在这一点上,你几乎总是希望重载.Equals()和.GetHashCode()以及让你的==重载调用.Equals()。