
Is Object.GetHashCode() unique to a reference or a value?关于Object.GetHashCode()的MSDN文档描述了该方法应如何工作的3个相互矛盾的规则。 规则1和3与我矛盾。 Object.GetHashCode()是否基于对象的值或对该对象的引用返回唯一数字。 如果我重写该方法,则可以选择要使用的方法,但是如果有人知道的话,我想知道内部使用的方法。
在一定程度上,它们是。原因很简单:如果将对象存储在哈希表中,并且通过更改其值来更改其哈希,则哈希表将丢失该值,并且无法通过查询哈希表再次找到它。重要的是,尽管对象存储在哈希表中,但它们保留其哈希值。 要实现这一点,通常最简单的做法是使可哈希对象不可变,从而避免整个问题。但是,仅使确定哈希值的那些字段不可变就足够了。 考虑以下示例:
人们很少更改生日,大多数人从不更改姓名(结婚时除外)。但是,它们的鞋号可能会任意增大,甚至会缩小。因此,合理地使用生日和姓名来识别人物,而不是鞋子的大小。哈希值应反映以下内容:
不确定要使用的MSDN文档。查看有关Object.GetHashCode的当前文档(http://msdn.microsoft.com/zh-cn/library/system.object.gethashcode.aspx)提供了以下"规则":
如果您指的是第二个要点,则此处的关键短语是"只要没有对对象状态进行任何修改"和"仅对于应用程序的当前执行为true"。 同样从文档中
至于实际的实现,它明确指出,当且仅当该派生类将值相等定义为引用相等并且类型不是值类型时,派生类才可以遵循Object.GetHashCode实现。换句话说,Object.GetHashCode的默认实现将基于引用相等性,因为没有要使用的实际实例字段,因此不能保证不同对象的唯一返回值。否则,您的实现应特定于您的类型,并应至少使用一个实例字段。例如,String.GetHashCode的实现针对相同的字符串值返回相同的哈希码,因此,如果两个String对象表示相同的字符串值,则它们返回相同的哈希码,并使用字符串中的所有字符生成该哈希值。 规则1和3并不是真正的矛盾。 对于引用类型,哈希码是从对对象的引用派生的-更改对象的属性,并且引用是相同的。 对于值类型,哈希码从值派生,更改值类型的属性,您将获得值类型的全新实例。
有关如何处理 我不确定在真正的.NET Framework中如何实现Object.GetHashCode,但是在Rotor中,它使用对象的SyncBlock索引作为哈希码。网络上有一些关于它的博客文章,但是大多数来自2005年。 默认情况下,它基于对对象的引用进行操作,但这意味着它是完全相同的对象,因此两者将返回相同的哈希值。但是像字符串类一样,散列应该基于该值。" a"和" b"将具有不同的哈希,但是" a"和" a"将返回相同的哈希。 |