C# 为什么GetHashCode在对象类中?
为什么是对象类的一部分?类的对象中只有一小部分用作哈希表中的键。当我们希望类的对象作为哈希表中的键时,使用一个必须实现的单独接口不是更好吗 MS团队决定将此方法包括在对象类中,从而使其“无处不在”,这肯定是有原因的C# 为什么GetHashCode在对象类中?,c#,.net,language-agnostic,clr,C#,.net,Language Agnostic,Clr,为什么是对象类的一部分?类的对象中只有一小部分用作哈希表中的键。当我们希望类的对象作为哈希表中的键时,使用一个必须实现的单独接口不是更好吗 MS团队决定将此方法包括在对象类中,从而使其“无处不在”,这肯定是有原因的 所以任何东西都可以输入。(索塔) 通过这种方式,HashTable可以将对象与实现ihashtable的对象进行比较 推动简单的平等比较 在不直接实现它的对象上,它默认为.NET的内部哈希代码,我认为这是对象实例的唯一ID,或者是它占用内存的哈希。(我记不清了,.NET Reflec
HashTable
可以将对象与实现ihashtable
的对象进行比较当使用诸如
HashSet
之类的东西时尤其如此-在这种情况下,对象引用通常用于跟踪和唯一性,而不一定作为“键”。如果哈希需要一个自定义接口,许多类将变得不那么有用。GetHashCode位于对象中,所以您可以将任何内容用作哈希表(一个基本容器类)的键。它提供了对称性。我可以把任何东西放进ArrayList,为什么不放进Hashtable呢
如果您需要类来实现IHashable,那么对于每个未实现IHashable的密封类,您将在希望将其用作包含哈希功能的键时编写适配器。相反,默认情况下您会得到它
此外,哈希代码是对象相等比较的第二行(第一行是指针相等)。它允许任何对象通过“标识”用作键。这在某些情况下是有益的,而在任何情况下都是有害的。那么,为什么不呢?如果每个类都有GetHashCode,那么您可以将每个对象放入哈希中。假设您有一个可以使用第三方对象(您无法修改)并希望将它们放入ab哈希中的实例。如果这些对象没有实现您虚构的
IHashable
,您就无法实现它。这显然是一件坏事;) 这是从Java、IMO复制的设计错误
在我完美的世界里:
将被重命名为ToString
,以适当设置期望值ToDebugString
和Equals
将消失GetHashCode
- 将有一个
实现ReferenceEqualityComparer
:这其中的equals部分目前很容易,但如果被重写,就无法获得“原始”哈希代码IEqualityComparer
- 对象不会有与其关联的监视器:
将有一个构造函数,Monitor
/Enter
等将是实例方法Exit
IEqualityComparer
),并且对象可以自己实现IEquatable
,我不明白为什么它应该在对象上EqualityComparer。如果T
未实现IEquatable
,则默认值可以使用参考实现,否则将遵循对象。生活将是愉快的
好吧。当我这么做的时候,阵列协方差是另一个平台错误。如果你想在C#中犯语言错误,如果你愿意,我可以再开始一次小的咆哮(到目前为止,这仍然是我最喜欢的语言,但有些事情我希望能有不同的做法。)
顺便说一句,我在别处看到过。只是猜测,但垃圾收集器可能会在内部存储某些对象的哈希表(可能是为了跟踪可终结的对象),这意味着任何对象都需要有哈希键。GetHashCode与比较无关-这是一个单独的问题。a.GetHashCode()等于a.GetHashCode(),但是b.GetHashCode()可以等于a.GetHashCode()。使用它“驱动简单的相等比较”是一个非常糟糕的主意。我怀疑它是在.NET开始大量使用接口之前(注意,GetHashCode
一直追溯到.NET 1.0)模仿java.lang.object
是的,您可以-您只需通过IEqualityComparer
告诉哈希表使用什么即可。非常简单。那么为什么要在GetHashCode
中写这个:“…这个方法的默认实现不能用作哈希目的的唯一对象标识符”?为什么会变得不那么有用?您只需指定一个适当的IEqualityComparer
实现,它可以是“通过引用进行比较”。事实上,EqualityComparer.Default
可以做到这一点。有关详细信息,请参见我的答案。@Jon:True-这需要单独指定,但可以很容易地完成-我的观点是,我反对要求对象本身实现接口-但单独指定就可以了。@ReedCopsey我完全不同意。在所有.NET和用户创建的所有项目中的所有类中,可能有0.0001%需要哈希/相等。在.NET本身中,基本类型/内置类型大约有15-20种(整数、字符串、枚举,可能是Guid,甚至不是小数/浮点数/日期/时间)。在大多数其他项目中,它是u