无法将keyValuePair直接添加到Dictionary

时间:2012-10-22 13:14:14

标签: c# dictionary key-value generic-collections

我想将KeyValuePair<T,U>添加到Dictionary<T, U>,但我不能。我必须分别传递密钥和值,这必然意味着Add方法必须创建一个新的KeyValuePair对象来插入,这不是非常有效。我无法相信Add方法上没有Add(KeyValuePair<T, U>)重载。任何人都可以提出这种明显疏忽的可能原因吗?

8 个答案:

答案 0 :(得分:32)

您可以使用提供IDictionary<TKey,TValue>方法的Add(KeyValuePair<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"));

答案 1 :(得分:32)

备份一分钟......在走向疏忽之路之前,你应该确定创建一个新的KeyValuePair是否真的如此低效。

首先,Dictionary类在内部不是作为一组键/值对实现的,而是作为一堆数组实现的。除此之外,让我们假设它只是一组KeyValuePairs并着眼于效率。

首先要注意的是KeyValuePair是一个结构。真正的含义是必须将它从堆栈复制到堆中才能作为方法参数传递。当KeyValuePair添加到字典中时,必须再次复制它以确保值类型语义。

为了将Key和Value作为参数传递,每个参数可以是值类型或引用类型。如果它们是值类型,则性能将与KeyValuePair路由非常相似。如果它们是引用类型,这实际上可以是更快的实现,因为只需要传递地址并且必须进行非常少的复制。在最佳情况和最差情况下,由于KeyValuePair结构本身的开销增加,此选项略好于KeyValuePair选项。

答案 2 :(得分:14)

有这样一种方法 - ICollection<KeyValuePair<K, T>>.Add但是因为显式实现了你需要将你的字典对象转换为该接口来访问它。

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

此方法的page包含一个示例。

答案 3 :(得分:2)

如果有人真的想这样做,这里有一个扩展

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

但如果没有真正需要这样做,我建议不要这样做

答案 4 :(得分:2)

除非我弄错了,否则.NET 4.5和4.6增加了将KeyValuePair添加到Dictionary的功能。 (如果我错了,请通知我,我会删除这个答案。)

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 :(得分:1)

只是因为Dictionary类的枚举器返回KeyValuePair,并不意味着它是如何在内部实现的。

如果你真的需要传递KVP,请使用IDictionary,因为你已经以这种格式获得了它们。否则使用赋值或只使用Add方法。

答案 6 :(得分:0)

将它作为扩展名添加到项目中会出现什么问题?

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);
        }
    }
}

答案 7 :(得分:-2)

我不是百分百肯定,但我认为Dictionary的内部实现是一个哈希表,这意味着键被转换为哈希以执行快速查找。

如果您想了解有关哈希表的更多信息,请阅读此处

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