Способ добавления нового или обновления существующего элемента в словаре
В некотором устаревшем коде я вижу следующий метод расширения, чтобы облегчить добавление нового элемента ключа или обновление значения, если ключ уже существует.
Метод-1 (устаревший код).
public static void CreateNewOrUpdateExisting<TKey, TValue>(
this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
if (map.ContainsKey(key))
{
map[key] = value;
}
else
{
map.Add(key, value);
}
}
Хотя, я проверил, что map[key]=value
выполняет точно такую же работу. То есть, этот метод может быть заменен Методом-2 ниже.
Метод-2.
public static void CreateNewOrUpdateExisting<TKey, TValue>(
this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
map[key] = value;
}
Теперь, мой вопрос: может ли быть какая-то проблема, если я заменил Method-1 на Method-2? Будет ли он нарушаться любым возможным сценарием?
Кроме того, я думаю, что это была разница между HashTable и Dictionary. HashTable позволяет обновлять элемент или добавлять новый элемент с помощью индексатора, пока словарь не работает! Разница устранена в версиях С# > 3.0?
Цель этого метода - не слишком исключение для исключения, если пользователь снова отправляет одно и то же значение ключа, метод должен просто обновить запись новым значением и создать новую запись, если была отправлена новая пара ключей-значений к методу.
Ответы
Ответ 1
Может ли быть какая-либо проблема, если я заменил метод-1 на метод-2?
Нет, просто используйте map[key] = value
. Эти два варианта эквивалентны.
Относительно Dictionary<>
vs. Hashtable
: при запуске Reflector вы увидите, что установщики индексатора обоих классов вызывают this.Insert(key, value, /* add */ false);
и параметр add
, ответственный за выброс исключения при вставке дублирующего ключа. Поэтому для обоих классов поведение одинаково.
Ответ 2
Нет проблем. Я бы даже удалил CreateNewOrUpdateExisting
из исходного кода и использовал map[key] = value
непосредственно в вашем коде, потому что это гораздо читаемо, потому что разработчики обычно знают, что означает map[key] = value
.
Ответ 3
Старый вопрос, но я чувствую, что должен добавить следующее, тем более, что .net 4.0 уже был запущен в момент написания вопроса.
Начиная с .net 4.0 существует пространство имен System.Collections.Concurrent
, которое содержит коллекции, которые являются потокобезопасными.
Коллекция System.Collections.Concurrent.ConcurrentDictionary<>
делает именно то, что вы хотите. Он имеет метод AddOrUpdate()
с дополнительным преимуществом обеспечения безопасности потоков.
Если вы используете высокопроизводительный сценарий и не обрабатываете несколько потоков, то уже заданные ответы map[key] = value
выполняются быстрее.
В большинстве сценариев это преимущество в производительности незначительно. Если так, я бы посоветовал использовать ConcurrentDictionary, потому что:
- Это в рамках - оно более проверено, и вы не тот, кто должен поддерживать код
- Он масштабируемый: если вы переключитесь на многопоточность, ваш код уже подготовлен для него
Ответ 4
Функционально они эквивалентны.
Производительность map[key] = value
будет быстрее, поскольку вы делаете только один поиск вместо двух.
По стилю, чем короче, тем лучше:)
В большинстве случаев код будет работать в многопоточном контексте. Тем не менее он не потокобезопасен без дополнительной синхронизации.