Словарь C# TryGetValue со значениями int, как избежать двойного поиска
при выполнении чего-то вроде:
int value;
if (dict.TryGetValue(key, out value))
{
if (condition)
{
//value = 0; this copies by value so it doesn't change the existing value
dict[key] = 0;
}
}
else
{
dict[key] = 0;
}
есть ли способ избежать поиска индекса для замены существующего значения? Я уже проверяю, что ключ существует с помощью TryGetValue, поэтому кажется пустой тратой снова получать значение по индексу.
на отдельной заметке, Как и в части else{} моего кода, обычно считается хорошей практикой использовать индексатор при добавлении новых или замене старых значений и добавлять, чтобы было ясно, что вы добавляете, а не заменяете? Или должен ли я просто использовать индексатор каждый раз? Как я научился пользоваться словарем, я всегда выполняю поиск TryGetValue и в части else обрабатываю случаи, когда ключа не существует.
3 ответов
есть ли способ избежать поиска индекса для замены существующего значения?
не то, что я знаю - но доступ к словарю должен быть очень быстро, если у вас нет пользовательского класса, который переопределен GetHashCode
плохо.
Если вы не видите проблемы с производительностью из-за двойного поиска, я бы оставил его в покое.
Я предпочитаю определять методы расширения удобства для таких вещей. Например:
public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue)
{
TValue value;
return dictionary.TryGetValue(key, out value) ? value : defaultValue;
}
public static TValue GetOrSet<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, TValue value)
{
return dictionary[key] = dictionary.GetValueOrDefault(key, value);
}
существует мало необходимости беспокоиться о производительности словаря хэширования и поисков - я в первую очередь обеспокоен удобочитаемостью и ремонтопригодностью. С помощью вышеуказанных методов расширения эта вещь является однострочной:
int value = dict.GetOrSet(key, 0);
(отказ от ответственности: не выполняет if (condition)
проверка-я редко испытываю эти сценарии)
вы можете попробовать это
Object value;
if (dict.TryGetValue(key, out value))
{
if (condition)
{
//value.data = 0; this copies by value so it doesn't change the existing value
value.data = 0;
}
}
else
{
value.data = 0;
}
суть истории в том, что тип, который вы извлекаете, является общим типом и выделяется в куче. то есть, когда вы вытащите его, он выйдет как ценность. Однако, если вытащить предмет, это будет ссылка на исходный выделенный объект и вы можете изменить значение определенного свойства объекта.