Страницы

Поиск по вопросам

пятница, 12 октября 2018 г.

Переопределение GetHashCode

Троелсен в своей книге, советует переопределить метод ToString() у класса(переопределенная версия возвращает строку из полей всего класса через пробел), а потом в методе GetHashCode вызывать this.ToString().GetHashCode()
Где-то читал критику такой реализации, например, вызов ToString() будет порождать мусор.
Правда ли, что она не очень хороша.
Какие могут быть альтернативы?


Ответ

Проблема со строкой состоит в том, что GetHashCode() может вызываться очень часто, много тысяч раз в секунду. Например, при поиске элемента в HashSet или поиске ключа в Dictionary у каждого искомого элемента берётся хэшкод. Если при этом будет каждый раз создаваться временная, никому за пределами метода не нужная строка, их потом должен будет очистить сборщик мусора.
Поэтому функция GetHashCode должна быть по возможности быстрой и не создавать дополнительных объектов.
По поводу того, как же лучше считать хэшкод, я бы посоветовал немного переделанный код из ответа @Umed:
public override int GetHashCode() { unchecked { int hash = 17; hash = hash * 23 + field1.GetHashCode(); // для поля типа-значения, например int hash = hash * 23 + field2.GetHashCode(); // то же самое if (field3 != null) // а это для поля ссылочного типа hash = hash * 23 + field3.GetHashCode(); return hash; } }
Вместо 17 и 23 можно взять другие разные простые числа.

Ещё по теме: Почему при переопределении Equals советуют также переопределять GetHashCode

Комментариев нет:

Отправить комментарий