С#. Переопределение метода GetHashCode [дубликат]

308
10 июня 2017, 12:27

На данный вопрос уже ответили:

  • Хешкод, переопределение метода GetHashCode 1 ответ
  • Почему при переопределении Equals советуют также переопределять GetHashCode 1 ответ

Здравствуйте!

Возник вопрос по поводу переопределения метода GetHashCode. Рассмотрим пример:

Есть класс Container, который просто хранит некоторые значения:

public class Container
{ 
    public int Number { get; set; }
    public string Text { get; set; }
    public bool IsFull { get; set; }
}

Для данного класса необходимо переопределить метод GetHashCode.

Вопрос: Есть ли какой-то шаблонный способ для реализации данного метода? Или здесь "у кого на что фантазии хватит"?

Приведу несколько примеров реализации методов, которые я смог найти и адаптировать к данному примеру (в ответе прошу объяснить, почему и в каких случаях та или иная реализация будет плохой или наоборот хорошей):

  1. Самая банальная идея - использовать реализацию метода класса Object (знаю, что это глупо, но пусть для примера будет такая реализация):

    public override int GetHashCode()
    {
        return base.GetHashCode();
    }
  2. Обычная сумма (или побитовая операция XOR) хеш-кодов всех свойств объекта:

    public override int GetHashCode()
    {
        unchecked
        {
            return Number.GetHashCode() + Text.GetHashCode() + IsFull.GetHashCode();
        }
    }
  3. Некоторый специфический алгоритм (умножение хеш-кода на простое число и др.):

    public override int GetHashCode()
    {
        int hashcode = Number.GetHashCode();
        hashcode = 31 * hashcode + Text.GetHashCode();
        hashcode = 31 * hashcode + IsFull.GetHashCode();
        return hashcode;
    }
Answer 1

Ну первая идея - действительно глупая (если хеш код планируется использовать), по одной простой причине: хеш код от object это хеш адреса объекта в памяти. Грубо говоря, два объекта с одинаковым содержимым буду выдавать разные хеши. Принципиально разные. Как следствие использовать их... Ну я думаю понятно).

А вот второй и третий имеют право на жизнь. Причем наверно ближе второй. Я не вижу если честно особой разницы в распределении (рандом умноженный на простое число остается рандомом), а возни меньше).

Кстати еще можно задать вопрос - для чего хеш будет использоваться? Если для словаря то пойдет второй. Если просто для сравнения объектов, проще Equals переопределить).

READ ALSO
Как экранировать символы в запросе MS SQL Server?

Как экранировать символы в запросе MS SQL Server?

Имеется программа на С#, работающая с MS SQL Server:

547
C# word поиск и вывод меток

C# word поиск и вывод меток

Добрый деньУ меня есть документ Doc

315
Не привязываются данные к модели

Не привязываются данные к модели

Когда данные приходят на WebApi контроллер, модель приходит, но в ней все строки nullРаспознаются только enumы

228
unrecognized database format в приложении C# Windows Form Application

unrecognized database format в приложении C# Windows Form Application

Добрый день, попросили создать простенькое приложение для учета техники, приложение я сделал, сперва создал в Access 2010 БД с таблицей и нужными...

246