40

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

4

8 回答 8

42

您可以使用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"));
于 2012-10-22T13:19:30.753 回答
39

备份一分钟......在继续监督之前,您应该确定创建新的 KeyValuePair 是否真的如此低效。

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

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

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

于 2012-10-22T13:24:21.220 回答
18

有这样一种方法——ICollection<KeyValuePair<K, T>>.Add但由于它是显式实现的,因此您需要将字典对象转换为该接口才能访问它。

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

此方法的页面包含一个示例。

于 2012-10-22T13:19:59.150 回答
2

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

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

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

于 2013-11-05T11:09:42.247 回答
2

除非我弄错了,.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 类型的新对象openWithopenWith然后使用该.Add方法创建并添加一个新的 KVP 对象。

于 2015-06-29T21:23:26.273 回答
1

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

如果您确实需要通过 KVP,请使用 IDictionary,因为您已经以该格式获得了它们。否则使用赋值或仅使用 Add 方法。

于 2012-10-22T13:26:11.517 回答
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);
        }
    }
}
于 2015-06-30T02:09:52.613 回答
-2

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

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

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

于 2012-10-22T13:22:40.677 回答