Frustration with the StringDictionary class.
Today I ran into an annoying nuance of the StringDictionary
class
(located in the System.Collections.Specialized
namespace so as not to
be confused with the other imposter string dictionaries). It’s not a
bug, but I feel the API for it could have been slightly better on this
minor point.
Right there in the documentation for the class it points out that:
The key is handled in a case-insensitive manner; it is translated to lower case before it is used with the string dictionary.
Thus it takes the key you give it, and changes it to a lower case value before storing it. I verified this with Reflector.
``
public virtual void Add(string key, string value)
{
this.contents.Add(key.ToLower(CultureInfo.InvariantCulture), value);
}
Whoa there! Stop the presses! Call Michael Moore! Ok, ok. So in the grand scheme of things, it’s a minor issue. It’s not a huge deal. However, API usability (and language design) focuses on keeping the minor annoyances to a minimum. Otherwise they’ll add up and form a major disturbance and soon you’ll have an angry developer standing on his/her soap box whining and ranting about it on a blog.
The issue for me is that this wasn’t the behavior I expected. If an API
is going to change data you give it, I wish it would indicate that
somehow. Perhaps the method could be
AddKeyAndValueButLowerCaseTheKey()
;). All joking aside, it isn’t
necessary to lower-case the key before storing it in order to provide
case-insensitive storage. Internally, StringDictionary
uses a
HashTable
to store its keys and values. The dictionary could have made
the HashTable
use a CaseInsensitiveHashCodeProvider
when storing
keys. That way the key doesn’t have to change, but you get case
insensitivity.
In any case, like I said, it’s normally not a big deal except for the
fact that I am building a Setup and Deployment project within Visual
Studio.NET for a Windows service. When building a project installer, the
Installer
(in the namespace System.Configuration.Install) class
provides a property called Context
of type InstallContext
. This
class gives you a property called Parameters
which is a
StringDictionary
containing values you may have pulled from the user
interface.
I’m trying to look up nodes within an XML file that correspond to the
keys of the Parameters
dictionary using XPath, hoping to update the
node values with the values from the dictionary. However, XPath is case
sensitive so I can’t match these things up. Unfortunately I can’t change
the XML to be all lower case, and I can’t change the Installer
class
to not use a StringDictionary
(or better yet, correct the dictionary’s
behavior), so I’m stuck with resorting to a hack until something better
comes along.
Comments
12 responses