Такое поведение предусмотрено дизайном, а дизайн - звуком.
Если бы класс взял на себя ответственность за то, чтобы не освобождать дубликаты, он должен был бы перебирать весь контейнер каждый раз, когда была произведена модификация, как добавление, так и удаление. Итерация проверит наличие дублирующихся значений и проверит соответственно.
Было бы катастрофически навязывать эту дьявольскую утечку производительности всем пользователям класса. Если вы хотите поместить дубликаты в список, вам нужно будет разработать политику управления сроком службы, соответствующую вашим конкретным потребностям. В этом случае нецелесообразно ожидать, что контейнер общего назначения будет поддерживать ваш конкретный шаблон использования.
В комментариях к этому ответу и многим другим было высказано предположение, что лучшим вариантом было бы проверить в AddOrSetValue
, было ли заданное значение уже присвоено указанной клавише. Если это так, то AddOrSetValue
может немедленно вернуться.
Я думаю, что всем ясно, что проверка на наличие дубликатов в полной общности слишком дорога, чтобы ее рассматривать. Тем не менее, я утверждаю, что есть веские конструктивные причины, по которым проверка на наличие дубликатов K и V в AddOrSetValue
также будет плохой конструкцией.
Помните, что TObjectDictionary<K,V>
является производным от TDictionary<K,V>
. Для более общего класса сравнение равенства V
является потенциально дорогостоящей операцией, поскольку у нас нет никаких ограничений относительно того, что такое V
, поскольку оно является общим. Таким образом, для TDictionary<K,V>
существуют причины, по которым мы не должны включать предполагаемый тест AddOrSetValue
.
Можно утверждать, что мы делаем специальное исключение для TObjectDictionary<K,V>
. Это, безусловно, было бы возможно. Это потребовало бы небольшой перестройки связи между двумя классами, но это вполне осуществимо. Но теперь у вас есть ситуация, когда TDictionary<K,V>
и TObjectDictionary<K,V>
имеют разную семантику. Это явный недостаток и должен быть сопоставлен с потенциальной выгодой от теста AddOrSetValue
.
Эти универсальные классы контейнеров настолько фундаментальны, что при проектировании необходимо учитывать огромное количество вариантов использования, соображений согласованности и так далее. На мой взгляд, не разумно рассматривать TObjectDictionary<K,V>.AddOrSetValue
в изоляции.