Мне сказали, что одна из многих причин, строки были сделаны неизменными в спецификации C#, состояла в том, чтобы избежать проблемы HashTables, изменяющего ключи, когда ссылки на строковые ключи изменили свое содержание.
Словарь <> тип позволяет ссылочным типам использоваться в качестве ключа. Как словарь избегает проблемы измененных ключей, которые приводят к "неуместным" значениям? Существует ли клон memberwise, сделанный из объекта при использовании в качестве ключа?
Тип Dictionary
не пытается защитить от изменения пользователем используемого ключа. Ответственность за то, чтобы ключ не изменялась, полностью остается на усмотрение разработчика.
Если вы немного задумаетесь, это действительно единственный разумный путь, который
Словарь
можно взять. Рассмотрим последствия выполнения такой операции, как поэлементное клонирование объекта. Чтобы быть тщательным, вам нужно сделать глубокое клонирование, потому что объект, на который есть ссылка в ключе, также может быть мутирован и, следовательно, повлиять на хэш-код. Итак, теперь каждый ключ, используемый в таблице, имеет клонированный полный граф объектов для защиты от мутации. Это будет и ошибочным, и, возможно, очень дорогостоящей операцией.
Класс Dictionary <>
ничего не делает для защиты от изменения изменяемого ключевого объекта. Вам решать, является ли класс, который вы используете в качестве ключа, изменяемым, и по возможности избегать этого.
Это не позволяет избежать этой ситуации. Это зависит от вызывающего кода:
Пока объект используется в качестве ключа в
Dictionary
, он не должен изменяться каким-либо образом, влияющим на его хэш-значение. . Каждый ключ вDictionary
должен быть уникальным в соответствии с компаратором равенства словаря. Ключ не может бытьнулевым
, но может иметь значение, если тип значенияTValue
является ссылочным типом.
(Из MSDN )
Если вы используете изменяемый ссылочный тип в качестве ключа, реализация по умолчанию GetHashCode ()
будет гарантировать равенство хешей независимо от состояния объекта (т. Е. Хеш привязан на ссылку, а не на государство). Однако вы правы, что изменяемый тип с семантикой равенства значений (где GetHashCode предположительно зависит от состояния) - плохой выбор для ключа словаря.