Не удается добавить keyValuePair непосредственно в словарь
Я хотел добавить KeyValuePair<T,U> до Dictionary<T, U> и я не мог. Я должен передать ключ и значение отдельно, что должно означать, что метод Add должен создать новый объект KeyValuePair для вставки, который не может быть очень эффективным. Я не могу поверить, что нет Add(KeyValuePair<T, U>) перегрузка метода Add. Может ли кто-нибудь предложить возможную причину этого очевидного недосмотра?
8 ответов
резервное копирование минуту...прежде чем идти по пути надзора, вы должны установить, действительно ли создание новой KeyValuePair настолько неэффективно.
во-первых, класс Dictionary внутренне не реализован как набор пар ключ/значение, но как куча массивов. Это в стороне, предположим, что это был просто набор KeyValuePairs и посмотрите на эффективность.
первое, что нужно заметить, это KeyValuePair - это структура. Реальные последствия этого это то, что он должен быть скопирован из стека в кучу, чтобы быть переданным как параметр метода. Когда KeyValuePair добавляется в словарь, его необходимо скопировать во второй раз, чтобы обеспечить семантику типа значения.
для того, чтобы передать ключ и значение в качестве параметров, каждый параметр может быть типом значения или ссылочным типом. Если это типы значений, производительность будет очень похожа на маршрут KeyValuePair. Если они являются ссылочными типами, это может быть более быстрая реализация, так как только адрес должен быть передан и очень мало копирования должно быть сделано. Как в лучшем, так и в худшем случае этот вариант незначительно лучше, чем вариант KeyValuePair из-за увеличения накладных расходов самой структуры KeyValuePair.
можно использовать IDictionary<TKey,TValue> интерфейс, который providese этот метод:
IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));
есть такой способ – ICollection<KeyValuePair<K, T>>.Add но как явно реализовано вам нужно привести свой объект словаря к этому интерфейсу, чтобы получить к нему доступ.
((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);
посмотреть
- список Явные Реализации Интерфейса on
Dictionary<K, T>страница документации (вам нужно прокрутить вниз). - явная реализация члена
на страница на этом метод включает в себя пример.
если я не ошибаюсь, .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 метод.
Если кто-то действительно делает это здесь, это расширение
public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
{
dic.Add(KVP.Key, KVP.Value);
}
но я бы рекомендовал не делать этого, если нет необходимости делать это
только потому, что перечислитель для класса Dictionary возвращает KeyValuePair, не означает, что он реализован внутренне.
используйте IDictionary, если вам действительно нужно передать KVP, потому что у вас уже есть их в этом формате. в противном случае используйте assignment или просто используйте метод Add.
что было бы неправильно просто добавить его в свой проект в качестве расширения?
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);
}
}
}
Я не уверен на 100%, но я думаю, что внутренняя реализация словаря-это хэш-таблица, Что означает, что ключи преобразуются в хэши для быстрого поиска.
прочитать здесь Если вы хотите знать больше о хеш-таблицы