Словарь C# <> и изменяемые ключи

Мне сказали, что одна из многих причин, строки были сделаны неизменными в спецификации C#, состояла в том, чтобы избежать проблемы HashTables, изменяющего ключи, когда ссылки на строковые ключи изменили свое содержание.

Словарь <> тип позволяет ссылочным типам использоваться в качестве ключа. Как словарь избегает проблемы измененных ключей, которые приводят к "неуместным" значениям? Существует ли клон memberwise, сделанный из объекта при использовании в качестве ключа?

9
задан Pierreten 9 June 2010 в 15:30
поделиться

4 ответа

Тип Dictionary не пытается защитить от изменения пользователем используемого ключа. Ответственность за то, чтобы ключ не изменялась, полностью остается на усмотрение разработчика.

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

9
ответ дан 4 December 2019 в 07:34
поделиться

Класс Dictionary <> ничего не делает для защиты от изменения изменяемого ключевого объекта. Вам решать, является ли класс, который вы используете в качестве ключа, изменяемым, и по возможности избегать этого.

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

Это не позволяет избежать этой ситуации. Это зависит от вызывающего кода:

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

(Из MSDN )

3
ответ дан 4 December 2019 в 07:34
поделиться

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

8
ответ дан 4 December 2019 в 07:34
поделиться
Другие вопросы по тегам:

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