我只是想确认一下我对一些基本原理的理解。希望你不介意!
我理解静态等于方法
Object.Equals(objA, objB)
首先检查参考相等性。如果不等于引用,则调用对象实例equals方法
objA.Equals(objB)
目前在我对equals的覆盖中,我首先检查引用相等性,如果不等于引用,则检查所有成员以查看语义是否相同。这是一个好方法吗?如果是这样,那么静态版本似乎是多余的?
对象的默认GetHashCode到底是做什么的?
如果我将我的对象添加到下面是HashTable的字典并且不重写equals和GetHashCode,那么我想我应该做的是使它最佳排序因此更好的检索时间?
答案 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。