Получение значений словаря - PullRequest
79 голосов
/ 18 декабря 2008

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

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

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

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

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

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

Какая практика лучше? Один быстрее другого? Я полагаю, что версия Try будет медленнее, поскольку она «проглатывает» try / catch внутри себя и использует это как логику, нет?

Ответы [ 3 ]

84 голосов
/ 18 декабря 2008

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

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

К вашему сведению: на самом деле это не ошибка.

Звонит:

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);
}
29 голосов
/ 18 декабря 2008

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

Edit:

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

Дело 1:

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

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

Дело 2:

myDict.TryGetValue(somekey, out someVal)

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

1 голос
/ 18 декабря 2008

Я думаю, что trygetvalue делает что-то похожее на:

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

Так что, надеюсь, никуда не денешься.

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

...