Кто-либо может объяснить, почему Словарь <> в C# разве работает, не любит карту <T, U> в STL?

Когда я сначала начал программировать в C# в прошлом году, я сразу искал эквивалент карте STL и узнал о Словаре.

ОБНОВЛЕНИЕ вычеркнуло этот мусор ниже, я был абсолютно неправ. Мой опыт с картой STL состоял в том, что я ненавидел, когда я запросил это на значение, и если бы ключ не был в карте, то это автоматически создало бы тип значения (независимо от того, что его конструктор по умолчанию сделал), и добавьте его к карте. Я должен был бы затем проверить на это условие в коде и выдать исключение.

Словарь <> получает целую корректную хижину - если ключ не там, это выдает исключение, если Вы запрашиваете значение, или автоматически добавляет его, если это не, и Вы хотите установить значение.

Но Вы все уже знали это. Я должен был записать свои модульные тесты прежде, чем отправить здесь и смущающий сам.:) Они записаны теперь!

Теперь я люблю Словарь и все, но вещь, которая прослушивает меня больше всего об этом прямо сейчас, состоит в том, что, если ключ не находится в Словаре, он бросает KeyNotFoundException. Поэтому я всегда должен писать код как это:

Dictionary<string,string> _mydic;

public string this[string key]
{
  get {
    return _mydic[key]; // could throw KeyNotFoundException
  }
  set {
    if( _mydic.ContainsKey( key))
      _mydic[key] = value;
    else
      _mydic.Add( key, value);
  }
}

Почему Словарь автоматически не добавляет пару значения ключа, если ключ не существует, как карта STL?

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

5
задан Dave 5 March 2010 в 18:30
поделиться

3 ответа

Какое значение вы бы хотели вернуть, если бы его еще не было на карте? Он мог вернуть значение по умолчанию (TValue) - но тогда было бы довольно легко случайно использовать значение, если оно было правильным. Обратите внимание, что если вам нужно такое поведение, вы можете использовать:

get {
  string value;
  if (!_mydic.TryGetValue(key, out value))
    value = default(string);
  return value;
}

Я бы лично не рекомендовал его в целом, но если вы счастливы, что не можете различать (с помощью этого индексатора) между ключом с нулевым значением и отсутствующий ключ, он сделает свое дело.

Обратите внимание, что ваш сеттер может быть намного проще - просто

_mydic[key] = value;

при необходимости перезапишет.

10
ответ дан 18 December 2019 в 14:44
поделиться

Я согласен, что обработка исключения немного раздражает, особенно для ссылочных типов, когда получение null обычно имеет смысл. Однако в любом случае вы можете использовать Dictionary<>.TryGetValue(), чтобы получить значение за один вызов.

3
ответ дан 18 December 2019 в 14:44
поделиться

Я запутался. Так и есть, здесь. В документации даже говорится об этом:

When you set the property value, if the key is in the Dictionary(TKey, TValue), the value associated with that key is replaced by the assigned value. If the key is not in the Dictionary(TKey, TValue), the key and value are added to the dictionary.

и

KeyNotFoundException: The property is retrieved and key does not exist in the collection.

(не упоминается, что он выбрасывается при присваивании).

0
ответ дан 18 December 2019 в 14:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: