Подтвердить что ты не робот

Различные способы добавления в словарь

В чем разница в Dictionary.add(key, value) и Dictionary[key] = value?

Я заметил, что последняя версия не бросает ArgumentException при вставке дублирующего ключа, но есть ли какие-то причины для предпочтения первой версии?

Изменить. Кто-нибудь имеет авторитетный источник информации об этом? Я пробовал MSDN, но это, как всегда, дикая охота на гусей: (

4b9b3361

Ответ 1

Производительность почти на 100% идентична. Вы можете проверить это, открыв класс в Reflector.net

Это указатель:

public TValue this[TKey key]
{
    get
    {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
            return this.entries[index].value;
        }
        ThrowHelper.ThrowKeyNotFoundException();
        return default(TValue);
    }
    set
    {
        this.Insert(key, value, false);
    }
}

И это метод Add:

public void Add(TKey key, TValue value)
{
    this.Insert(key, value, true);
}

Я не буду публиковать весь метод Insert, поскольку он довольно длинный, однако это объявление метода:

private void Insert(TKey key, TValue value, bool add)

И далее в функции это происходит:

if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key))
{
    if (add)
    {
        ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
    }

Что проверяет, существует ли ключ уже существующий, и если он это делает, а параметр add - true, он выдает исключение.

Итак, для всех целей и намерений производительность одинакова.

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

Извините за длинный пост, я надеюсь, что все в порядке.

Ответ 2

Первая версия добавит новый ключ KeyValuePair в словарь, бросая, если ключ уже находится в словаре. Второй, используя индекс, добавит новую пару, если ключ не существует, но перезапишите значение ключа, если оно уже существует в словаре.

IDictionary<string, string> strings = new Dictionary<string, string>();

strings["foo"] = "bar";          //strings["foo"] == "bar"
strings["foo"] = string.Empty;   //strings["foo"] == string.empty
strings.Add("foo", "bar");       //throws     

Ответ 3

Dictionary.Add(key, value) и Dictionary[key] = value имеют разные цели:

  • Используйте метод Add для добавления новой пары ключ/значение, существующие ключи не будут заменены (вызывается ArgumentException).
  • Используйте индексатор, если вам все равно, существует ли ключ в словаре, другими словами: добавьте пару ключ/значение, если ключ не находится в словаре, или замените значение для указанного ключа, если ключ уже находится в словаре.

Ответ 4

Чтобы сначала ответить на вопрос, нам нужно взглянуть на цель словаря и основополагающих технологий.

Dictionary - это список KeyValuePair<Tkey, Tvalue>, где каждое значение представлено его уникальным ключом. Скажем, у нас есть список ваших любимых блюд. Каждое значение (название пищи) представлено его уникальным ключом (позиция = насколько вам нравится эта еда).

Пример кода:

Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
    { 1, "Burger"},
    { 2, "Fries"},
    { 3, "Donuts"}
};

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

/*your key stays 1, you only replace the value assigned to this key
  you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";

Но не забывайте, что вы программист, и с этого момента вы заканчиваете свои предложения; вы отказываетесь использовать emojis, потому что они будут бросать ошибку компиляции, а весь список избранных - на основе индекса.

Ваша диета тоже изменилась! Таким образом, вы снова измените свой список:

/*you don't want to replace Salad, you want to add this new fancy 0
  position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";

/*or Add it*/
myDietFavorites.Add(0, "Pizza");

Есть две возможности с определением: вы либо хотите дать новое определение для чего-то, чего раньше не было, или вы хотите изменить определение, которое уже существует.

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

Теперь мы будем смотреть под капот. Когда вы создаете словарь, ваш компилятор делает резервирование для ведра (пробелы в памяти для хранения ваших записей). Ведро не хранит ключи так, как вы их определяете. Каждый ключ хэшируется перед тем, как перейти в ведро (определено Microsoft), стоит упомянуть, что значение части остается неизменным.

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

myDietFavorites[0] = "Pizza";

Что происходит с ведром: db2dc565 "Пицца" (упрощенный).

Когда вы изменяете значение с помощью:

myDietFavorites[0] = "Spaghetti";

У вас есть x, который снова будет db2dc565, тогда вы найдете это значение в своем ковше, чтобы найти его там. Если он там, вы просто переписываете значение, назначенное ключу. Если это не так, вы поместите свое значение в ведро.

Когда вы вызываете функцию Добавить в свой словарь, например:

myDietFavorite.Add(0, "Chocolate");

У вас есть хэш, чтобы сравнить его с единицами в ведре. Вы можете поместить его в ведро , только если он не там.

Очень важно знать, как это работает, особенно если вы работаете со словарями типа string или char. Он чувствителен к регистру из-за хэширования. Так, например, "name" != "Name". Позвольте использовать наш CRC32, чтобы изобразить это.

Значение для "name": e04112b1 Значение для "Имя": 1107fb5b

Ответ 5

Да, в этом и заключается разница, метод Add генерирует исключение, если ключ уже существует.

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

Ответ 6

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

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

dict[key] = value представляет собой лучшую замену. Если я увижу этот код, я бы предпочел, что ключ уже находится в словаре.

Ответ 7

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