为什么GetHashCode是Object类的一部分?只有一小部分对象用作哈希表中的键。当我们希望类的对象作为哈希表中的键时,必须实现一个单独的接口,这不是更好吗。
MS团队决定将此方法包含在Object类中,从而使其“随处可用”。
答案 0 :(得分:17)
这是从Java,IMO复制的设计错误。
在我完美的世界里:
ToString
将重命名为ToDebugString
以正确设置期望Equals
和GetHashCode
将会消失ReferenceEqualityComparer
会有一个IEqualityComparer<T>
实现:此时平等的部分很容易,但如果被覆盖则无法获得“原始”哈希码Monitor
将具有构造函数,Enter
/ Exit
等将是实例方法。 Equality(以及哈希)通常会导致继承层次结构中出现问题 - 只要您始终可以指定要使用的比较类型(通过IEqualityComparer<T>
),对象就可以自己实现IEquatable<T>
如果他们愿意,我不明白为什么它应该在Object
。如果EqualityComparer<T>.Default
未实现T
,则IEquatable<T>
可以使用参考实现,否则将遵从这些对象。生活会很愉快。
我在其他地方blogged about this,顺便说一下。
答案 1 :(得分:3)
只有一小部分对象被用作哈希表中的键
我认为这不是一个真实的陈述。许多类通常用作哈希表中的键 - 并且经常使用对象引用本身。 System.Object中存在GetHashCode的默认实现意味着任何对象都可以用作键,没有限制。
这似乎比在对象上强制自定义接口要好得多,只是为了能够对它们进行哈希处理。您永远不知道何时需要将对象用作散列集合中的键。
在使用像HashSet<T>
这样的东西时尤其如此 - 在这种情况下,通常,对象引用用于跟踪和唯一性,而不一定是“密钥”。如果散列需要一个自定义接口,那么许多类将变得不那么有用。
答案 2 :(得分:1)
它允许任何对象被“身份”用作键。这在某些情况下是有益的,而在任何情况下都是有害的那么,为什么不呢?
答案 3 :(得分:0)
HashTable
可以将对象与实现IHashable
的对象进行对比。在没有直接实现它的对象上,它默认为.NET的内部哈希代码,我认为它是对象实例的唯一ID或它占用的内存占用的哈希值。 (我不记得了,.NET Reflector无法超越该类的.NET组件。)
答案 4 :(得分:0)
GetHashCode位于对象中,因此您可以将任何内容用作Hashtable(一个基本容器类)的键。它提供对称性。我可以把任何东西放到ArrayList中,为什么不是Hashtable?
如果您需要类来实现IHashable,那么对于每个未实现IHashable的密封类,当您想要将其用作包含散列功能的密钥时,您将编写适配器。相反,你默认得到它。
此外,Hashcodes是对象相等性比较的第二行(第一行是指针相等)。
答案 5 :(得分:0)
如果每个类都有GetHashCode,则可以将每个对象放在哈希中。想象一下,您有一个使用第三方对象(您无法修改)并希望将它们放入ab哈希。如果这些对象没有实现虚构IHashable
,那么你无法做到。这显然是一件坏事;)
答案 6 :(得分:0)
只是一个猜测,但垃圾收集器可能在内部存储一些对象的哈希表(可能是为了跟踪可终结的对象),这意味着任何对象都需要一个哈希键。