GetHashCode Equality - PullRequest
       1

GetHashCode Equality

5 голосов
/ 12 октября 2010

Мне было интересно об этом, поэтому я решил спросить.

В большинстве мест, которые вы увидите, используется та же семантическая логика для переопределения Equals, что и для GetHashCode для членского равенства ... однако обычно онииспользуйте разные реализации:

    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;
    }

Если вы реализуете равноправное членство для своего типа (скажем, для сохранения в словаре), почему бы просто не переопределить 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 ]

10 голосов
/ 12 октября 2010

Потому что - это реальный риск конфликтов. Хеш-коды не уникальны. Они могут (когда разные) доказать неравенство, но никогда не равенство. При поиске товара:

  • получить хеш-код (ы)
  • если хеш-код другой, объект другой; откажитесь от этого
  • если хеш-код совпадает, установите флажок Equals:
  • если отчеты равны true они одинаковы
  • еще сбросить

Рассмотрим long ..., поскольку хэш-код int, легко увидеть, что существует множество конфликтов.

1 голос
/ 12 октября 2010

Хэши не 1-к-1, у вас может быть несколько разных значений, которые хэшируют к одному и тому же значению, но которые должны сравниваться как не равные.Таким образом, вы не можете реально реализовать Equals с точки зрения GetHashCode.Вот почему у вас есть коллизии в хеш-таблице, и поэтому поиск в хеш-таблице должен включать вызовы как GetHashCode, так и Equals.

...