代码之家  ›  专栏  ›  技术社区  ›  Jeff

GetHashCode相等

  •  5
  • Jeff  · 技术社区  · 14 年前

    我想知道这件事,所以我想我会问的。

    您将看到的大多数地方都使用相同的语义逻辑来重写equals作为gethashcode以实现memberwise相等…但是它们通常使用不同的实现:

        public override bool Equals(object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return false;
            }
            var other = (MyType)obj;
            if (other.Prop1 != Prop1)
            {
                return false;
            }
            return true;
        }
    
        public override int GetHashCode()
        {
            int hash = -657803396;
            num ^= Prop1.GetHashCode();
            return num;
        }
    

    如果您正在为您的类型实现memberwise相等(比如存储在字典中),为什么不重写gethashcode,然后对equals执行如下操作:

        public override bool Equals(object obj)
        {
            return this.HashEqualsAndIsSameType(obj);
        }
    
        public static bool HashEquals(this object source, object obj)
        {
            if (source != null && obj != null)
            {
                return source.GetHashCode() == obj.GetHashCode();
            }
            if (source != null || obj != null)
            {
                return false;
            }
            return true;
        }
    
        public static bool HashEqualsAndIsSameType<T>(this T source, object obj)
        {
            return (obj == null || obj.GetType() == typeof(T)) && source.HashEquals(obj);
        }
    
    2 回复  |  直到 14 年前
        1
  •  10
  •   Marc Gravell    14 年前

    因为那里 真正的冲突风险。哈希代码是 独特的。他们可以证明不平等,但决不能证明平等。查找项目时:

    • 获取哈希代码
    • 如果散列代码不同,则对象不同;放弃它
    • 如果哈希代码相同,则检查等于:
    • 如果等于报表 true 它们是一样的
    • 否则丢弃

    考虑 long …因为哈希代码是 int 很容易看出有很多很多冲突。

        2
  •  1
  •   Eloff    14 年前

    哈希值不是1对1,您可以有多个不同的值,这些值哈希到相同的值,但应该比较为不相等。所以不能真正实现gethashcode中的equals。这就是为什么哈希表中存在冲突,以及哈希表查找必须同时调用GetHashCode和Equals的原因。