【问题标题】:NameValueCollection vs Dictionary<string,string> [duplicate]NameValueCollection 与 Dictionary<string,string> [重复]
【发布时间】:2011-03-01 09:00:59
【问题描述】:

可能重复:
IDictionary<string, string> or NameValueCollection

有什么理由我应该使用 Dictionary 而不是 NameValueCollection?

(在 C#/.NET 框架中)

选项 1,使用 NameValueCollection:

//enter values:
NameValueCollection nvc = new NameValueCollection()
{
  {"key1", "value1"},
  {"key2", "value2"},
  {"key3", "value3"}
};

// retrieve values:
foreach(string key in nvc.AllKeys)
{
  string value = nvc[key];
  // do something
}

选项 2,使用 Dictionary...

//enter values:
Dictionary<string, string> dict = new Dictionary<string, string>()
{
  {"key1", "value1"},
  {"key2", "value2"},
  {"key3", "value3"}
};

// retrieve values:
foreach (KeyValuePair<string, string> kvp in dict)
{
  string key = kvp.Key;
  string val = kvp.Value;
  // do something
}

对于这些用例,使用其中一种与另一种相比有什么优势吗?在性能、内存使用、排序顺序等方面有什么不同吗?

【问题讨论】:

    标签: c# .net collections dictionary namevaluecollection


    【解决方案1】:

    它们在语义上并不相同。 NameValueCollection 可以有重复的键,而Dictionary 不能。

    就个人而言,如果您没有重复的密钥,那么我会坚持使用Dictionary。它更现代,使用IEnumerable&lt;&gt;,可以轻松与Linq 查询混合。您甚至可以使用Linq ToDictionary() 方法创建Dictionary。

    【讨论】:

    • 如果你有重复的键,你也可以使用.ToLookup(o =&gt; [key], o =&gt; [value(s)]),它应该(?)表现得像一个只读字典。
    • NameValueCollection 继承自 NameObjectCollectionBase,后者实现了 IEnumerable,因此它也可用于 LINQ 的枚举和使用。
    【解决方案2】:

    NameValueCollection 是string 类型化的,而Dictionary 利用泛型来允许类型变化。见Benefits of Generics。

    【讨论】:

    • NameValueCollection 是强类型的。它到处使用字符串。根本没有对象引用。
    • 感谢@LoneCoder,已修复。
    【解决方案3】:

    Dictionary 会快得多。 NameValueCollection 允许重复键。这在某些情况下可能是不好的,或者在其他情况下是需要的。 Dictionary 不允许重复键。

    发件人:http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

    Dictionary&lt;(Of &lt;(TKey, TValue&gt;)&gt;) 泛型类提供从 一组值的一组键。每个 除了字典包括 一个值及其关联的键。 使用其键检索值是 非常快,接近O(1),因为 Dictionary&lt;(Of &lt;(TKey, TValue&gt;)&gt;) 类被实现为一个哈希表。

    【讨论】:

    • 但是你为什么声称 NameValueCollection 不 是作为一个哈希表实现的呢?我看到很多人声称这样,但我没有发现任何文件或参考资料表明这一点。尽管如此,我确实认识到,如果将 NameValueCollection for 用于 QueryStrings,那么他们应该 not 使用哈希表,因为哈希表会 slower 对于大多数情况。您声称 Dictionary 更快,但这仅适用于大型列表。小列表,如 10 个键,通常在没有哈希表的情况下更快。因此,我要求您小心地将任何“更快”的东西称为一揽子声明;视情况而定。
    • @ShawnKovac:这不是我声称 NVC 没有实现为哈希表。这是 MSDN 的直接引用。随时检查我的复制粘贴文本! :)
    • MSDN 在哪里声称 NVC 没有实现为哈希表?我找不到,实际上我发现了相反的情况,尽管没有直接说明。但是 MSDN 显示 NameValueCollection 是从 NameObjectCollectionBase 继承的,在 NameObjectCollectionBase 页面上,Remarks 下的第一句话是“该类的底层结构是一个哈希表”。 msdn.microsoft.com/en-us/library/…
    • 感谢您的链接,但我发现与您在那篇文章中声称的完全相反。您刚刚链接的文章有这样的确切文本:“NameValueCollection 实际上将哈希键查找委托给内部哈希表,该哈希表可能包含与该键关联的多个条目。”因此,根据这篇文章,NVC 确实 使用哈希表查找名称,并具有可以包含具有相同键的多个项目的附加功能。但我不明白为什么他们不只使用普通的哈希表并在键已经存在的情况下组合值。
    • 微软的这个链接清楚地表明它确实使用了“哈希键查找”,这是我最初的问题。我现在也明白,当我写“哈希表”时,你理解我的意思是 .NET HashTable,这不是我的意思。我的意思是泛指,否则可以表示为键名的“快速二进制搜索”。这确实是雷士使用的。所以我认为我们都同意 NVC 不是 .NET HashTable 但它确实使用快速二进制搜索算法来快速找到密钥(.NET 称之为“哈希键查找”,我称之为“哈希表” ')。
    猜你喜欢
    • 2017-06-07
    • 2010-09-24
    • 2010-10-12
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 2012-09-21
    • 2012-03-01
    • 1970-01-01
    相关资源
    最近更新 更多