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

Невозможно добавить keyValuePair прямо в словарь

Я хотел добавить KeyValuePair<T,U> в Dictionary<T, U>, и я не мог. Мне нужно передать ключ и значение отдельно, что должно означать, что метод Add должен создать новый объект KeyValuePair для вставки, что не может быть очень эффективным. Я не могу поверить, что в методе добавления не существует перегрузки Add(KeyValuePair<T, U>). Может ли кто-нибудь предположить возможную причину такого явного надзора?

4b9b3361

Ответ 1

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

Во-первых, класс Dictionary не внутренне реализуется как набор пар ключ/значение, а как совокупность массивов. В стороне, допустим, это всего лишь набор KeyValuePairs и посмотрите на эффективность.

Первое, что нужно заметить, это KeyValuePair - это структура. Реальная импликация заключается в том, что она должна быть скопирована из стека в кучу, чтобы быть переданной в качестве параметра метода. Когда KeyValuePair добавляется в словарь, его нужно будет скопировать второй раз, чтобы обеспечить семантику типа значения.

Чтобы передать параметры "ключ" и "значение как параметр", каждый параметр может быть либо типом значения, либо ссылочным типом. Если они являются типами значений, производительность будет очень похожа на маршрут KeyValuePair. Если они являются ссылочными типами, это фактически может быть более быстрой реализацией, так как только адрес должен быть передан, и очень малое копирование должно быть выполнено. Как в лучшем случае, так и в худшем случае эта опция немного лучше, чем опция KeyValuePair из-за увеличения накладных расходов самой структуры KeyValuePair.

Ответ 2

Вы можете использовать интерфейс IDictionary<TKey,TValue>, который предоставляет этот метод:

IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));

Ответ 3

Существует такой метод - ICollection<KeyValuePair<K, T>>.Add, но, поскольку он явно реализован, вам нужно отправить свой словарь на этот интерфейс для доступа к нему.

((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);

См

страница в этом методе включает пример.

Ответ 4

Если я ошибаюсь,.NET 4.5 и 4.6 добавляет возможность добавления KeyValuePair в словарь. (Если я ошибаюсь, просто сообщите мне, и я удалю этот ответ.)

https://msdn.microsoft.com/en-us/library/cc673027%28v=vs.110%29.aspx

Из приведенной выше ссылки соответствующий фрагмент информации является примером этого кода:

public static void Main() 
{
    // Create a new dictionary of strings, with string keys, and 
    // access it through the generic ICollection interface. The 
    // generic ICollection interface views the dictionary as a 
    // collection of KeyValuePair objects with the same type 
    // arguments as the dictionary. 
    //
    ICollection<KeyValuePair<String, String>> openWith =
        new Dictionary<String, String>();

    // Add some elements to the dictionary. When elements are  
    // added through the ICollection<T> interface, the keys 
    // and values must be wrapped in KeyValuePair objects. 
    //
    openWith.Add(new KeyValuePair<String,String>("txt", "notepad.exe"));
    openWith.Add(new KeyValuePair<String,String>("bmp", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("dib", "paint.exe"));
    openWith.Add(new KeyValuePair<String,String>("rtf", "wordpad.exe"));

    ...
}

Как можно видеть, создается новый объект типа Dictionary, который называется openWith. Затем создается новый объект KVP и добавляется к openWith с помощью метода .Add.

Ответ 5

Если кто-то действительно делает это, это расширение

    public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
    {
        dic.Add(KVP.Key, KVP.Value);
    }

но я бы рекомендовал не делать этого, если нет реальной необходимости делать это

Ответ 6

просто потому, что перечислитель класса Dictionary возвращает KeyValuePair, не означает, что он реализован внутри.

используйте IDictionary, если вам действительно нужно передать KVP, потому что вы уже получили их в этом формате. в противном случае используйте назначение или просто используйте метод Add.

Ответ 7

Что было бы неправильно, только добавив его в свой проект как расширение?

namespace System.Collection.Generic
{
    public static class DictionaryExtensions
    {
        public static void AddKeyValuePair<K,V>(this IDictionary<K, V> me, KeyValuePair<K, V> other)
        {
            me.Add(other.Key, other.Value);
        }
    }
}

Ответ 8

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

Прочитайте здесь, если вы хотите узнать больше о hashtables

http://en.wikipedia.org/wiki/Hash_table