staticObject.Equals方法,GetHashCode和Dictionary类的默认实现

本文关键字:默认 实现 Dictionary Equals 方法 GetHashCode staticObject | 更新日期: 2023-09-27 18:21:25

我只想确认一下我对一些基本知识的理解。希望你不要介意!

我了解静态相等方法

Object.Equals(objA, objB)

首先检查引用相等性。如果引用不相等,则调用对象实例等于方法

objA.Equals(objB)

目前,在我的equals覆盖中,我首先检查引用是否相等,如果不相等,则与所有成员一起检查语义是否相同。这是一个好方法吗?如果是这样,那么静态版本似乎是多余的?

此外,对象的默认GetHashCode究竟做了什么?

如果我把我的对象添加到下面是HashTable的字典中,并且不覆盖equals和GetHashCode,那么我想我应该做些什么来优化它的排序,从而获得更好的检索时间?

staticObject.Equals方法,GetHashCode和Dictionary类的默认实现

当前在我的equals覆盖中,我首先检查参考平等,如果不平等,请与所有成员核实看看语义是否相同。这是一个好方法吗?如果是,那么静态版本似乎是多余的?

是的,进行快速引用相等性检查是个好主意。不能保证您的方法将通过静态Object.Equals方法进行调用,它也可以直接调用。例如,EqualityComparer<T>.Default(相等性检查的典型中间人)在许多情况下(当类型不实现IEquatable<T>时)将直接调用此方法,而无需首先进行引用相等性检查。

此外,对象的默认GetHashCode究竟做了什么?

它转发到RuntimeHelpers.GetHashCode:一个神奇的内部实现的CLR方法,它是引用相等的兼容GetHashCode实现。有关更多信息,请参阅Object.GetHashCode()的默认实现。无论何时重写Equals,都必须重写它。

编辑:

如果我将我的对象添加到字典中,该字典是下面的HashTable,并且不要重写equals和GetHashCode,那么我想我应该这样做使其进行最佳排序,从而获得更好的检索时间?

如果你不重写这两个,你会得到(可能)一个平衡良好的表的引用相等。如果您覆盖其中一个而不覆盖另一个,或者以任何其他不兼容的方式实现它们,您将得到一个损坏的哈希表。

顺便说一句,散列和排序是完全不同的。

有关更多信息,请参阅在C#中重写Equals方法时,为什么重写GetHashCode很重要?

你的第一个问题已经回答了,但我认为第二个问题还没有完全回答。

如果您想将对象用作哈希表或字典中的键,那么实现GetHashCode非常重要。它最大限度地减少了冲突,因此加快了查找速度。当两个或多个键具有相同的哈希代码并且调用了这些equals方法时,就会发生查找冲突。如果哈希代码是唯一的,那么equals将只被调用一次,否则将为具有相同哈希代码的每个键调用它,直到equals返回true。