Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么GetHashCode在对象类中?_C#_.net_Language Agnostic_Clr - Fatal编程技术网

C# 为什么GetHashCode在对象类中?

C# 为什么GetHashCode在对象类中?,c#,.net,language-agnostic,clr,C#,.net,Language Agnostic,Clr,为什么是对象类的一部分?类的对象中只有一小部分用作哈希表中的键。当我们希望类的对象作为哈希表中的键时,使用一个必须实现的单独接口不是更好吗 MS团队决定将此方法包括在对象类中,从而使其“无处不在”,这肯定是有原因的 所以任何东西都可以输入。(索塔) 通过这种方式,HashTable可以将对象与实现ihashtable的对象进行比较 推动简单的平等比较 在不直接实现它的对象上,它默认为.NET的内部哈希代码,我认为这是对象实例的唯一ID,或者是它占用内存的哈希。(我记不清了,.NET Reflec

为什么是对象类的一部分?类的对象中只有一小部分用作哈希表中的键。当我们希望类的对象作为哈希表中的键时,使用一个必须实现的单独接口不是更好吗

MS团队决定将此方法包括在对象类中,从而使其“无处不在”,这肯定是有原因的

  • 所以任何东西都可以输入。(索塔)
  • 通过这种方式,
    HashTable
    可以将对象与实现
    ihashtable
    的对象进行比较
  • 推动简单的平等比较
  • 在不直接实现它的对象上,它默认为.NET的内部哈希代码,我认为这是对象实例的唯一ID,或者是它占用内存的哈希。(我记不清了,.NET Reflector无法通过类的.NET组件)

    类的对象中只有一小部分用作哈希表中的键

    我认为这不是一个真实的说法。许多类经常被用作哈希表中的键,对象引用本身也经常被使用。System.Object中存在GetHashCode的默认实现意味着任何对象都可以用作键,而不受任何限制

    这似乎比在对象上强制使用自定义接口要好得多,只是为了能够散列它们。您永远不知道何时可能需要在哈希集合中使用对象作为键


    当使用诸如
    HashSet
    之类的东西时尤其如此-在这种情况下,对象引用通常用于跟踪和唯一性,而不一定作为“键”。如果哈希需要一个自定义接口,许多类将变得不那么有用。

    GetHashCode位于对象中,所以您可以将任何内容用作哈希表(一个基本容器类)的键。它提供了对称性。我可以把任何东西放进ArrayList,为什么不放进Hashtable呢

    如果您需要类来实现IHashable,那么对于每个未实现IHashable的密封类,您将在希望将其用作包含哈希功能的键时编写适配器。相反,默认情况下您会得到它


    此外,哈希代码是对象相等比较的第二行(第一行是指针相等)。

    它允许任何对象通过“标识”用作键。这在某些情况下是有益的,而在任何情况下都是有害的。那么,为什么不呢?

    如果每个类都有GetHashCode,那么您可以将每个对象放入哈希中。假设您有一个可以使用第三方对象(您无法修改)并希望将它们放入ab哈希中的实例。如果这些对象没有实现您虚构的
    IHashable
    ,您就无法实现它。这显然是一件坏事;)

    这是从Java、IMO复制的设计错误

    在我完美的世界里:

    • ToString
      将被重命名为
      ToDebugString
      ,以适当设置期望值
    • Equals
      GetHashCode
      将消失
    • 将有一个
      ReferenceEqualityComparer
      实现
      IEqualityComparer
      :这其中的equals部分目前很容易,但如果被重写,就无法获得“原始”哈希代码
    • 对象不会有与其关联的监视器:
      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