为什么在重载相等运算符时,您希望覆盖GetHashCode和Equals?

eva*_*nal 5 .net c# operator-overloading

无法覆盖GetHashCode以及Equals重载等于运算符时导致编译器产生警告.为什么改变其中任何一个的实现是个好主意?在阅读了Eric Lippert关于GetHashCode的博客文章之后,似乎可能没有很多有用的替代GetHashCode的基础实现,为什么编译器我鼓励你改变它?

Eri*_*ert 9

我们假设你正在实现一个类.

如果您正在重载,==那么您将生成一个具有值相等而不是引用相等的类型.

鉴于此,现在的问题是"有一个实现引用相等的类.Equals()和值相等的类是多么令人满意==?" 答案是"不太理想".这似乎是混淆的潜在根源.(事实上​​,我现在为公司工作的公司Coverity生产了一个缺陷发现工具,可以检查你是否将价值平等与参考平等混淆,正是出于这个原因.巧合的是,当我看到它时,我只是在读它的规格.你的问题!)

而且,如果你要有一个同时实现值和引用相等的类,通常的做法是覆盖Equals==单独留下,而不是相反.

因此,鉴于您已经超载==,强烈建议您也覆盖Equals.

如果你要重写Equals产生价值相等,那么你需要覆盖GetHashCode才能匹配,因为你知道如果你读过我链接到的文章.

  • @evanmcdonnal:永远不可能使用引用相等; 只需使用`Object.ReferenceEquals(x,y)`或`(object)x ==(object)y`,无论对象超载或覆盖什么,您都将获得引用相等性. (6认同)
  • @evanmcdonnal如果你想实现值相等,你可以通过`Equals()`和*not*via` ==`来实现它.如果只通过重写`==`来实现值相等,则所有Linq都会失败,因为它使用`Equals()`而不是'==`来确定值相等.许多其他标准.Net库类也是如此,例如`Dictionary <>` (2认同)