Почему GetHashCode находится в Классе объекта?

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

Должна быть причина, что команда MS решила включать этот метод в Класс объекта и таким образом сделать его доступным "везде".

8
задан Incognito 22 June 2010 в 18:31
поделиться

7 ответов

Это была дизайнерская ошибка, скопированная из Java, IMO.

В моем идеальном мире:

  • ToString будет переименован в ToDebugString , чтобы установить ожидания соответствующим образом
  • Equals и GetHashCode исчезнут
  • Была бы реализация ReferenceEqualityComparer для IEqualityComparer : равная часть в данный момент легко, но нет способа получить «исходный» хэш-код, если он переопределен
  • С объектами не будут связаны мониторы: Монитор будет иметь конструктор, а Enter / Exit и т. Д. Будут методами экземпляра.

Равенство (и, следовательно, хеширование) вызывает проблемы в иерархиях наследования в целом - если вы всегда можете указать тип сравнения, который хотите использовать (через IEqualityComparer ), и объекты могут реализовать IEquatable сами, если они хотят, я не понимаю, почему он должен быть на объекте . EqualityComparer .Default может использовать эталонную реализацию, если T не реализует IEquatable , и в противном случае откладывается на объекты. Жить было бы приятно.

Ну что ж. Пока я занимаюсь этим, ковариация массивов была еще одной ошибкой платформы.Если вам нужны языковые ошибки в C #, я могу начать еще одну небольшую тираду, если хотите;) (Это все еще мой любимый язык, но есть вещи, которые я хотел бы сделать по-другому.)

Я написал в блоге об этом в другом месте, кстати.

17
ответ дан 5 December 2019 в 07:56
поделиться

GetHashCode находится в объекте, поэтому вы можете использовать что угодно в качестве ключа в Hashtable, базовом классе контейнера. Это обеспечивает симметрию. Я могу поместить что угодно в ArrayList, почему бы не в Hashtable?

Если вам требуются классы для реализации IHashable, то для каждого запечатанного класса, который не реализует IHashable, вы будете писать адаптеры, если хотите использовать его в качестве ключа, включающего возможность хеширования. Вместо этого вы получаете его по умолчанию.

Также хэш-коды являются хорошей второй строкой для сравнения равенства объектов (первая строка - равенство указателя).

0
ответ дан 5 December 2019 в 07:56
поделиться

Если у каждого класса есть GetHashCode, вы можете поместить каждый объект в хеш. Представьте, что вам нужно использовать сторонние объекты (которые вы не можете изменить) и вы хотите поместить их в хэш ab. Если бы эти объекты не реализовали ваш вымышленный IHashable , вы бы не смогли этого сделать. Это явно плохо;)

0
ответ дан 5 December 2019 в 07:56
поделиться

Лишь небольшая часть объектов классов используется в качестве ключей в хеш-таблицах

Я бы сказал, что это неверное утверждение. Многие классы часто используются в качестве ключей в хэш-таблицах - и очень часто используются сами ссылки на объекты. Наличие реализации GetHashCode по умолчанию в System.Object означает, что ЛЮБОЙ объект может использоваться в качестве ключа без ограничений.

Это кажется намного лучше, чем принудительное использование настраиваемого интерфейса для объектов только для того, чтобы иметь возможность их хэшировать. Никогда не знаешь, когда может понадобиться использовать объект в качестве ключа в хешированной коллекции.

Это особенно верно при использовании таких вещей, как HashSet - в этом случае часто ссылка на объект используется для отслеживания и уникальности, не обязательно в качестве «ключа». Если бы хеширование требовало настраиваемого интерфейса, многие классы стали бы гораздо менее полезными.

3
ответ дан 5 December 2019 в 07:56
поделиться
  1. Так что все может быть включено. (Sorta)
  2. Таким образом, HashTable может брать объект вместо того, что, например, реализует IHashable .
  3. Управлять простым сравнением на равенство.

Для объектов, которые не реализуют его напрямую, по умолчанию используется внутренний хэш-код .NET, который, как мне кажется, является либо уникальным идентификатором экземпляра объекта, либо хешем занимаемой им памяти. (Я не могу вспомнить, а .NET Reflector не может пройти мимо .NET-компонента класса).

0
ответ дан 5 December 2019 в 07:56
поделиться

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

0
ответ дан 5 December 2019 в 07:56
поделиться

Это позволяет любой объект, который будет использоваться в качестве ключа "идентичностью". В некоторых случаях это полезно и ни в коем случае не вредно. Так почему бы и нет?

1
ответ дан 5 December 2019 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: