Получение наилучших практических рекомендаций по использованию словаря

Недавно я заметил Dictionary.TryGetValue(TKey key, out TValue value), и мне было любопытно, какой из них лучше подходит для получения значения из Словаря.

Я традиционно делал:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

если я не знаю, что он должен быть там.

Лучше просто сделать:

if (myDict.TryGetValue(somekey, out someVal)
    ...

Какая из них лучше? Быстрее, чем другой? Я бы предположил, что версия Try будет медленнее, чем ее "глотание" try/catch внутри себя и использование этого как логики, no?

Спасибо!

Ответ 1

TryGetValue немного быстрее, потому что FindEntry будет вызываться только один раз.

Сколько быстрее? Это зависит от набор данных под рукой. Когда вы вызываете Содержит метод, словарь выполняет внутренний поиск, чтобы найти его индекс. Если он возвращает true, вам нужно другое индексный поиск, чтобы получить фактическое значение. Когда вы используете TryGetValue, он ищет только один раз для индекса и если он найден, он присваивает значение вашей переменной.

FYI: На самом деле это не ошибка.

Он вызывает:

public bool TryGetValue(TKey key, out TValue value)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        value = this.entries[index].value;
        return true;
    }
    value = default(TValue);
    return false;
}

ContainsKey:

public bool ContainsKey(TKey key)
{
    return (this.FindEntry(key) >= 0);
}

Ответ 2

На самом деле TryGetValue работает быстрее. Насколько быстрее? Это зависит от набора данных. Когда вы вызываете метод Contains, словарь выполняет внутренний поиск, чтобы найти его индекс. Если он возвращает true, вам нужен другой поиск индекса, чтобы получить фактическое значение. Когда вы используете TryGetValue, он ищет только один раз для индекса, и если он найден, он присваивает значение вашей переменной.

Edit:

Хорошо, я понимаю ваше замешательство, поэтому позвольте мне уточнить:

Случай 1:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];

В этом случае есть два вызова FindEntry, один из которых проверяет, существует ли ключ, и один для его получения.

Случай 2:

myDict.TryGetValue(somekey, out someVal)

В этом случае есть только один вызов FindKey, потому что полученный индекс сохраняется для фактического поиска в том же методе.

Ответ 3

Я предполагаю, что trygetvalue делает что-то большее:

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;

Так что, надеюсь, нигде не пытайтесь/поймать.

Я думаю, что это просто метод удобства. Я обычно использую его, поскольку он сохраняет строку кода или два.