C # как вычислить хеш-код из ссылки на объект - PullRequest
14 голосов
/ 31 мая 2010

Ребята, у вас острая проблема!

Часть системы TickZoom должна собирать экземпляры каждого типа объекта в словарь типа <>.

Обязательно, чтобы их равенство и хэш-код основывались на экземпляре объекта, что означает ссылочное равенство, а не равенство значений. Проблема состоит в том, что некоторые объекты в системе имеют переопределенные Equals () и GetHashCode () для использования в качестве равенства значений, и их внутренние значения со временем изменятся. Это означает, что их Equals и GetHashCode бесполезны. Как решить это в общем, а не навязчиво?

Пока что мы создали структуру, чтобы обернуть каждый объект с именем ObjectHandle для хеширования в Словарь. Как вы видите ниже, мы реализовали Equals (), но проблема с вычислением хеш-кода остается.

public struct ObjectHandle : IEquatable<ObjectHandle>{
    public object Object;
    public bool Equals(ObjectHandle other) {
        return object.ReferenceEquals(this.Object,other.Object);
    }
}

См? Существует метод object.ReferenceEquals (), который сравнивает равенство ссылок без учета какой-либо переопределенной реализации Equals () в объекте.

Теперь, как рассчитать соответствующий GetHashCode (), рассматривая только ссылку, не беспокоясь о каком-либо переопределенном методе GetHashCode ()?

Ах, надеюсь, это даст вам интересную загадку. Мы застряли здесь.

С уважением, Wayne

Ответы [ 3 ]

19 голосов
/ 31 мая 2010

RuntimeHelpers.GetHashCode () делает именно то, что здесь необходимо.

2 голосов
/ 31 мая 2010

Вы нарушаете схему, это приводит к вопросам, которые не могут быть решены. Метод Equals должен сравнивать содержимое объектов, а не сравнивать ссылки. Это то, что делает object.Equals, зачем переопределять то же поведение?

Теперь о GetHashCode. Опять же, хеш-код - это хеш-функция, применяемая к содержимому объекта. Вы не можете рассчитать это только по ссылке. Вы можете использовать указатель на объект и использовать его в качестве хэша, но в GC адреса объектов .net могут быть изменены.

0 голосов
/ 31 мая 2010

Хеш-код не должен быть уникальным. (Но уникальность улучшит производительность).
Итак, одну вещь, которую вы можете сделать, это установить хэш-код по имени типа. Все объекты одного типа будут иметь одинаковый хеш-код.

...