C# Can';不要将keyValuePair直接添加到字典中
我想将C# Can';不要将keyValuePair直接添加到字典中,c#,dictionary,key-value,generic-collections,C#,Dictionary,Key Value,Generic Collections,我想将KeyValuePair添加到Dictionary中,但我做不到。我必须分别传递键和值,这意味着Add方法必须创建一个新的KeyValuePair对象来插入,这不是很有效。我不敢相信Add方法上没有Add(KeyValuePair)重载。有人能提出这种明显疏忽的可能原因吗?您可以使用IDictionary界面,该界面提供了Add(KeyValuePair)方法: IDictionary<int, string> dictionary = new Dictionary<in
KeyValuePair
添加到Dictionary
中,但我做不到。我必须分别传递键和值,这意味着Add方法必须创建一个新的KeyValuePair对象来插入,这不是很有效。我不敢相信Add方法上没有Add(KeyValuePair)
重载。有人能提出这种明显疏忽的可能原因吗?您可以使用IDictionary
界面,该界面提供了Add(KeyValuePair)
方法:
IDictionary<int, string> dictionary = new Dictionary<int, string>();
dictionary.Add(new KeyValuePair<int,string>(0,"0"));
dictionary.Add(new KeyValuePair<int,string>(1,"1"));
IDictionary dictionary=newdictionary();
添加(新的键值对(0,“0”);
添加(新的KeyValuePair(1,“1”));
有这样一种方法–ICollection.Add
,但由于它是显式实现的,您需要将dictionary对象强制转换到该接口以访问它
((ICollection<KeyValuePair<KeyType, ValueType>>)myDict).Add(myPair);
((ICollection)myDict.Add(myPair);
看
- 在的文档页面上的显式接口实现列表(您需要向下滚动)
这个方法的示例。我不是100%确定,但我认为字典的内部实现是一个哈希表,这意味着将键转换为哈希以执行快速查找 如果您想了解更多关于哈希表的信息,请阅读此处
备份一分钟……在走上监督之路之前,您应该确定创建新的KeyValuePair是否真的如此低效
首先,Dictionary类不是作为一组键/值对在内部实现的,而是作为一组数组实现的。除此之外,让我们假设它只是一组KeyValuePairs,然后看看效率 首先要注意的是结构。这意味着它必须从堆栈复制到堆,才能作为方法参数传递。将KeyValuePair添加到字典时,必须再次复制它以确保值类型语义
为了将键和值作为参数传递,每个参数可以是值类型或引用类型。如果它们是值类型,则性能将非常类似于KeyValuePair路由。如果它们是引用类型,这实际上是一个更快的实现,因为只需要传递地址,只需进行很少的复制。在最佳和最坏情况下,由于KeyValuePair结构本身的开销增加,此选项略优于KeyValuePair选项。仅仅因为Dictionary类的枚举器返回KeyValuePair,并不意味着它是如何在内部实现的
如果确实需要传递KVP,请使用IDictionary,因为您已经获得了该格式的KVP。否则使用赋值或直接使用Add方法。如果有人真的想这样做,这里有一个扩展
public static void Add<T, U>(this IDictionary<T, U> dic, KeyValuePair<T, U> KVP)
{
dic.Add(KVP.Key, KVP.Value);
}
公共静态无效添加(此IDictionary dic,KeyValuePair KVP)
{
dic.Add(KVP.Key,KVP.Value);
}
但是如果没有必要这样做,我建议不要这样做,除非我弄错了,.NET 4.5和4.6增加了向字典中添加KeyValuePair的功能。(如果我错了,请通知我,我将删除此答案。) 通过以上链接,相关信息如下代码示例:
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"));
...
}
publicstaticvoidmain()
{
//创建一个新的字符串字典,包括字符串键和
//通过通用ICollection接口访问它
//通用ICollection接口将字典视为
//具有相同类型的KeyValuePair对象的集合
//作为字典的参数。
//
ICollection openWith=
新字典();
//在字典中添加一些元素。当元素
//通过ICollection界面添加
//和值必须包装在KeyValuePair对象中。
//
openWith.Add(新的键值对(“txt”,“notepad.exe”);
openWith.Add(新的KeyValuePair(“bmp”、“paint.exe”);
openWith.Add(新的KeyValuePair(“dib”、“paint.exe”);
openWith.Add(新的KeyValuePair(“rtf”、“wordpad.exe”);
...
}
可以看到,创建了一个新的Dictionary类型的对象,称为
openWith
。然后创建一个新的KVP对象,并使用.Add
方法将其添加到openWith
中。将其作为扩展添加到项目中会有什么问题
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);
}
}
}
namespace System.Collection.Generic
{
公共静态类字典扩展
{
公共静态无效AddKeyValuePair(此IDictionary me,KeyValuePair其他)
{
me.Add(other.Key,other.Value);
}
}
}
没有这种重载,因为字典不仅仅“插入”新的KeyValuePair。(我甚至怀疑它是否以这种格式存储在引擎盖下)它测试密钥是否已经存在,并可能执行一些操作将其放置在正确的位置,以尽可能快地保持查询;您的键和值的类型是什么?我认为您可以忽略“Add”方法的开销。您也可以使用dictionary.Add(pair.key,pair.value),其中pair是KVP object。请注意,此方法只调用Add(KVP.key,KVP.value)
@Rawling是的,在大多数情况下都是这样,但这取决于IDictionary接口的实现(例如,排序字典以调用Add(kvp.Key,kvp.Value)以外的其他方式实现它)。尽管正确,但这与问题无关。So-1。(即使是哈希表也需要存储原始值来处理冲突和枚举键。)这个问题显然是由于缺乏对词典内部工作原理的理解。我的回答使他能够自己回答这个问题和进一步的问题,或者至少在哪里寻找答案。我并不完全同意。是的,有假设