Почему GetHashCode находится в классе Object? - PullRequest
8 голосов
/ 22 июня 2010

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

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

Ответы [ 7 ]

17 голосов
/ 22 июня 2010

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

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

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

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

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

3 голосов
/ 22 июня 2010

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

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

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

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

1 голос
/ 22 июня 2010

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

0 голосов
/ 24 июня 2010

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

0 голосов
/ 22 июня 2010

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

0 голосов
/ 22 июня 2010

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

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

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

0 голосов
/ 22 июня 2010
  1. Так что все можно включить.(Сорта)
  2. Таким образом HashTable может взять объект против чего-то, что реализует, например, IHashable.
  3. Для простого сравнения на равенство.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...