【问题标题】:Using incremental number as GetHashCode return value使用增量数字作为 GetHashCode 返回值
【发布时间】:2013-12-03 12:04:31
【问题描述】:

我想让 X 类的每个实例都具有唯一的 ID。
我正在使用递增的数字来执行此操作:

class X {
    private int id;
    private static int instanceCounter = 0;

    public X() {
        id = Interlocked.Increment(ref instanceCounter);
    }

    //...
}

这些对象也用作字典中的键,所以我想我可以从GetHashCode() 返回id

    public override int GetHashCode() {
        return id;
    }

我知道Eric Lippert's post,但它总是谈论从存储在对象中的多个数据计算哈希值。
就我而言,唯一的“独特”数据是id

所以问题是:
这种方法有什么我没有想到的吗?

【问题讨论】:

    标签: c# hash unique


    【解决方案1】:

    如果您希望每个对象都不同(因此不等于任何其他对象),那么根本不要覆盖 EqualsGetHashCode。默认设置是提供一个“可能唯一”的哈希码,这是您缩小选择范围所需的全部 - 而Equals 将使用您想要的引用标识。不需要单独的 id 字段,只是为了相等。

    如果您确实出于其他原因需要 id 字段,您当然可以从 GetHashCode 返回它 - 我建议将其设为只读字段以明确您的意图。

    请注意,无论如何都不应将哈希码用作 确定 肯定相等检查 - 它们仅用于排除绝对彼此相等的实例.

    【讨论】:

    • 默认的GetHashCode是如何实现的?我被困在[MethodImplAttribute(MethodImplOptions.InternalCall)] ...
    • @joe:是的,它是内部的,有效的。你不必担心它。如果您在覆盖 Object.GetHashCode 时仍需要获取该哈希码,则始终可以使用 RuntimeHelpers.GetHashCode(object)
    【解决方案2】:

    如果您只关心 Equals() 是否正常工作,您可以像这样覆盖 GetHashCode

    public override int GetHashCode() {
        return 0;
    }
    

    意思是每次都必须调用 Equals();这在逻辑方面很好,但可能会导致性能方面的问题(这将有效地使任何具有此类的哈希表具有检索复杂度 O(n) 而不是 O(1));但是对于小列表(数十个项目)应该没问题。

    【讨论】:

      猜你喜欢
      • 2013-06-05
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 2015-10-20
      • 2016-04-10
      • 1970-01-01
      • 2022-11-29
      相关资源
      最近更新 更多