【问题标题】:What is the best way of combining two uints into an int for overridding GetHashCode()?将两个单元组合成一个 int 以覆盖 GetHashCode() 的最佳方法是什么?
【发布时间】:2011-05-13 19:15:53
【问题描述】:

我有一个基于两个 uint 值覆盖 Equals 的类。因为我已经覆盖了 Equals,所以我需要覆盖 GetHashCode。

一个 uint 值代表一个永远不应该有重复的 id。它不一定是自动递增的 int 值,但在大多数情况下应该是。第二个 uint 值表示对象的类型字段。

仅使用 ID 字段就足够了。但在某些情况下它可能有点限制,这就是我想结合 ID 和类型的原因。

我想将这两个数字相加,然后使用 XOR 组合高位和低位。

还有其他想法吗?

【问题讨论】:

  • uint ID字段真的能占据uint的整个范围吗?
  • 但在某些情况下可能会有点限制 - 您能否详细解释一下仅使用 ID 字段对您来说限制过多的情况?
  • 如果我有多个会话对不同的实体开放,那么可以使用相同的 ID。然而,我的班级应该不关心这个会话,所以我不想考虑它,因为那时我有泄漏的实现。所以我认为跨不同会话的对象具有完全相同的类型和 ID 的可能性非常小。但也许我不应该在意。他们可以编写自定义比较器来考虑这一点。也许我应该只使用 ID。

标签: c# .net


【解决方案1】:

散列码仅用于在基于散列的集合中分发项目,例如 Dictionary,因此散列码在理想情况下应该尽可能少地产生冲突。

然而,最低要求只是哈希码对于任何给定的值集应该始终相同。因此,即使这是一个有效的哈希码算法:

public int GetHashCode() {
  return 1;
}

尽管它的分布很糟糕,但它仍然可以正常工作。

如果您想在哈希码中同时使用 Id 和 Type,您可以将它们异或在一起:

public int GetHashCode() {
  return (int)Id ^ (int)Type;
}

【讨论】:

    【解决方案2】:

    如果您知道永远不会(或很少)有重复的 id,那么您就可以使用它。

    但一般来说,要获得两个整数 ab 的良好 HashCode,您可以选择一个小的素数 p 并计算 a + p * b

    【讨论】:

    • 我只是担心溢出,因为某些类型在 uint 范围的最末端具有 uint 值。
    • @uriDium:默认溢出被忽略(未选中)。此处是否溢出无关紧要-即使发生溢出,哈希码仍然可用。
    猜你喜欢
    • 2010-09-20
    • 2010-11-15
    • 2010-12-22
    • 2011-02-13
    • 2010-12-23
    • 1970-01-01
    • 2016-02-05
    • 1970-01-01
    相关资源
    最近更新 更多