Почему словарь не обращается к несуществующим ключам, как это делает Hashtable? - PullRequest
5 голосов
/ 30 декабря 2008

Если я использую Hashtable, я могу написать такой код:

object item = hashtable[key] ?? default_value;

Это работает независимо от того, появляется ли key в Hashtable.

Я не могу сделать это с Dictionary<TKey. TValue>. Если ключ отсутствует в словаре, будет выброшено KeyNotFoundException. Поэтому я должен написать код, подобный этому:

MyClass item;
if (!(dict.TryGetValue(key, out item))
{
   item = default_value;
}

Мне интересно, почему это так. Dictionary<TKey, TValue> - это просто оболочка вокруг Hashtable. Почему это ограничение было добавлено к нему?

Edit:

Что касается другого взгляда на ответ PopCatalin (см. Ниже), код, который я написал выше, не будет работать, если значения словаря имеют тип значения. Если я использую Dictionary<int, int>, то код, который я хотел бы использовать , выглядит следующим образом:

int i = dict[key] ?? default_value;

И это не скомпилируется, потому что dict[key] не является обнуляемым или ссылочным типом.

Ответы [ 6 ]

8 голосов
/ 30 декабря 2008

Разница между Dictionary<T> и Hashtable заключается в том, что Dictionary<T> является универсальным типом, который может специализироваться для хранения типов значений вдоль ссылочных типов.

В хеш-таблице могут храниться только ссылочные типы (Object, переданные по ссылке) и только типы значений, помещенные в квадрат (также переданные по ссылке).

Когда словарь специализируется на типах значений, он должен возвращать эти значения «по значению», а не по ссылке. Таким образом, Dictionary<T> не может возвращать ноль, так как ноль не является допустимым значением для типов значений.

4 голосов
/ 30 декабря 2008

В вашем сообщении есть одно заблуждение. Словарь не является оберткой вокруг Hashtable. Это совершенно другая реализация.

Причина, по которой было сделано это изменение, в основном оправдывается одним утверждением: нулевое значение является допустимым значением для хеш-таблицы Без этого изменения невозможно различить несуществующий ключ и ключ значения с нулевым значением, используя метод доступа []. Словарь проясняет это.

2 голосов
/ 30 декабря 2008

Я написал расширение для этого.

public static class DictionaryExtension
{
    public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> items, string key)
    {
        if (items != null && items.ContainsKey(key))
        {
            return items[key];
        }

        return default(TValue);
    }
}
1 голос
/ 30 декабря 2008

Dictionary.ContainsKey, вероятно, лучше для вас, чем TryGetValue.

А вот почему, понятия не имею.

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

Если вы посмотрите на код с помощью Reflector, вы увидите, что Dictionary пытается найти ключ, и явно вызывает исключение, если не находит ключ.

public TValue get_Item(TKey key)
{
    int index = this.FindEntry(key);
    if (index >= 0)
    {
        return this.entries[index].value;
    }
    ThrowHelper.ThrowKeyNotFoundException();
    return default(TValue);
}
0 голосов
/ 30 декабря 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...