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

时间:2012-01-26 14:23:53

标签: c# .net dictionary

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

我理解静态等于方法

Object.Equals(objA, objB)

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

objA.Equals(objB)

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

对象的默认GetHashCode到底是做什么的?

如果我将我的对象添加到下面是HashTable的字典并且不重写equals和GetHashCode,那么我想我应该做的是使它最佳排序因此更好的检索时间?

2 个答案:

答案 0 :(得分:2)

  

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

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

  

对象的默认GetHashCode到底是做什么的?

它转发到RuntimeHelpers.GetHashCode:一个神奇的,内部实现的CLR方法,它是一个符合引用相等性的GetHashCode实现。有关更多信息,请参阅Default implementation for Object.GetHashCode()。无论何时覆盖Equals,都应该覆盖它。

修改

  

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

如果你不重写,你将获得与(可能)一个平衡良好的表的引用相等。 如果你覆盖一个而不是另一个,或者以任何其他不合规的方式实现它们,你将获得一个破碎的哈希表。

顺便说一句,hashing与排序完全不同。

有关详细信息,请参阅Why is it important to override GetHashCode when Equals method is overriden in C#?

答案 1 :(得分:2)

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

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