NameValueCollection vs Dictionary<string,string> [duplicate]
Asked Answered
S

3

108

Possible Duplicate:
IDictionary<string, string> or NameValueCollection

Any reason I should use Dictionary<string,string> instead of NameValueCollection?

(in C# / .NET Framework)

Option 1, using 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
}

Option 2, using Dictionary<string,string>...

//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
}

For these use cases, is there any advantage to use one versus the other? Any difference in performance, memory use, sort order, etc.?

Sihonn answered 8/6, 2010 at 20:39 Comment(0)
I
136

They aren't semantically identical. The NameValueCollection can have duplicate keys while the Dictionary cannot.

Personally if you don't have duplicate keys, then I would stick with the Dictionary. It's more modern, uses IEnumerable<> which makes it easy to mingle with Linq queries. You can even create a Dictionary using the Linq ToDictionary() method.

Igal answered 8/6, 2010 at 20:41 Comment(2)
You can also use .ToLookup(o => [key], o => [value(s)]) if you have duplicate keys, and it should (?) behave like a readonly dictionary.Embrue
NameValueCollection inherits from NameObjectCollectionBase which implements IEnumerable so it is also enumerable and usable with LINQ.Nestle
V
20

NameValueCollection is string typed whereas Dictionary leverages generics to allow type variance. See Benefits of Generics.

Volume answered 8/6, 2010 at 20:55 Comment(2)
NameValueCollection is strongly typed. It's using strings everywhere. No object references at all.Pera
Thanks @LoneCoder, fixed it.Volume
M
11

Dictionary will be much faster. NameValueCollection allows duplicate keys. Which could be bad in certain situations, or desired in other. Dictionary does not allow duplicate keys.

From: http://msdn.microsoft.com/en-us/library/xfhwa508.aspx

The Dictionary<(Of <(TKey, TValue>)>) generic class provides a mapping from a set of keys to a set of values. Each addition to the dictionary consists of a value and its associated key. Retrieving a value by using its key is very fast, close to O(1), because the Dictionary<(Of <(TKey, TValue>)>) class is implemented as a hash table.

Mozza answered 8/6, 2010 at 20:59 Comment(11)
But why do you claim that NameValueCollection is not implimented as a hash table? I see many people claim such, but i've found no documentation or references indicating such. Altho i do recognize that if a NameValueCollection was made for use for QueryStrings, then they shud not use a hash table because the hash table wud be slower for most instances. You claim the Dictionary is faster, but that's only true for large lists. Small lists, like with 10 keys, are normally faster without hash tables. So i ask you to be careful to call anything 'faster' as a blanket statement; it depends.Thundering
@ShawnKovac: That's not me claiming that NVC is not implemented as a hash table. That's a direct quote from MSDN. Feel free to back-check my copy-paste text! :)Mozza
where does MSDN claim than NVC is not not implemented as a hash table? i can't find that, and i actually found the opposite, altho not stated directly. But MSDN shows the NameValueCollection is inherited from NameObjectCollectionBase and on the NameObjectCollectionBase page, the first sentence under Remarks is "The underlying structure for this class is a hash table." msdn.microsoft.com/en-us/library/…Thundering
Putting those two facts together, we can arrive at the deduction that MSDN documentation indeed claims that NameValueCollection is implemented with a hash table as the underlying structure, which means that it shud be as fast as an IDictionary for large collections, and as slow as an IDictionary for small collections. (not that i think it's truly slow at all, but compared to a simple non-hash table, the IDictionary will be slower.)Thundering
@ShawnKovac: interesting, but wrong deduction. Here's another link: blogs.msdn.microsoft.com/bclteam/2006/09/05/…. This is a Microsoft BCL team member clearly stating that NVC is not using Hashtable.Mozza
thanks for the link, but i find the exact opposite of what you are claiming in that article. The article you just linked has this exact text: "NameValueCollection actually delegates the hash key lookups to an internal Hashtable, which may contain multiple entries associated with that key." So according to this article, a NVC does use a hashtable lookup for names, with the added feature that it can contain multiple items with the same key. But i don't understand why they don't just use a normal hashtable and combine the values if the key already exists.Thundering
Oh, now it seems to me that a NVC is also indexed numerically while a Dictionary and Hashtable are not. So that's a reason why they don't just combine the values. (I'm just answering my own 'why don't they ...' in my previous comment.)Thundering
@ShawnKovac: MSDN says, "This collection is based on the NameObjectCollectionBase class. However, unlike the NameObjectCollectionBase, this class stores multiple string values under a single key." - nothing on this page says anything about hashtable. Also, you can't have duplicate keys in a hashtable, which is what you're implying. Finally, one more RTM: "Collections of this type do not preserve the ordering of element, and no particular ordering is guaranteed when enumerating the collection.". So no, NVC is not ordered numerically.Mozza
on Jun 20, in this conversation, (just a few comments up, you provided this link: blogs.msdn.microsoft.com/bclteam/2006/09/05/… If you go there, you will find that it contains 'Hashtable' 17 times. This is the article i mean when i wrote on Jun 22, "thanks for the link" and the rest of that comment of mine. I understand that a .NET HashTable cannot have duplicate keys, while NaveValueCollection can. That does not mean the underlying collection doesn't use a hash table lookup.Thundering
And this link at Microsoft clearly states that it indeed DOES use a 'hash key lookup', which is what my initial question was. I also understand now that when i wrote 'hash table' you understood me to mean a .NET HashTable which is NOT what i meant. I meant it generically, which could otherwise be expressed as a 'quick binary search' for the key name. And this is indeed what NVC uses. So i think we both agree that that a NVC is not a .NET HashTable but it does use a quick binary search algorithm to find the key quickly (which .NET calls a 'hash key lookup', and i called a 'hashtable').Thundering
Thanks for pointing out that NVC does not guarantee any order. You have enlightened me to that Microsoft quirk. However, i would not express it as 'NVC is not ordered numerically', since they do have a numerical index, but their numerical index is simply not guaranteed to be the same as the source/input. Happy coding!Thundering

© 2022 - 2024 — McMap. All rights reserved.