Frans Bouma's blog

Generator.CreateCoolTool();

Syndication

News




    Add to Technorati Favorites

About me

Fun stuff I created

My work

Dictionary<TKey, TValue> vs. Hashtable() tip

If you're porting code from .NET 1.x to .NET 2.0, like I'm doing at the moment, and your .NET 1.x code uses Hashtables(), be aware of the following if you decide to migrate your Hashtables to Dictionary<TKey, TValue> variables.

In .NET 1.x, you'd do:

Hashtable myData = new Hashtable();
//... fill it

SomeType value = (SomeType)myData[key];
if(value==null)
{
   // key not there, handle...
}
now, if you port this to .NET 2.0, you normally end up with this code:
Dictionary<KeyType, SomeType> myData = new Dictionary<KeyType, SomeType>();
//... fill it

SomeType value = myData[key];
if(value==null)
{
   // key not there, handle...
}
Though, this doesn't work. It compiles ok, but something changed in .NET 2.0: if key isn't found, you no longer get null back but you get a nice exception. So the code above should be reworked to:
Dictionary<KeyType, SomeType> myData = new Dictionary<KeyType, SomeType>();
//... fill it

SomeType value = null;
if(!myData.ContainsKey(key))
{
   // key not there, handle...
}
else
{
   value = myData[key];
}
The sad part is: often the code to port isn't small, and you first try to get it compiled. If you don't keep the above difference in mind, you'll probably have a lovely time fixing bugs after the tests have run. So you've been warned

UPDATE: Wilco Bauwer posted in the comments another work-around, which is even more preferable: TryGetValue(). Sometimes you overlook the most obvious things!
Reworking my example above, it will look like:

Dictionary<KeyType, SomeType> myData = new Dictionary<KeyType, SomeType>();
//... fill it

SomeType value = null;
if(!myData.TryGetValue(key, out value))
{
   // key not there, handle...
}

Published Monday, December 12, 2005 4:07 PM by FransBouma

Filed under:

Comments

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Monday, December 12, 2005 10:14 AM

You should use TryGetValue instead. It has an out parameter and returns true/false if the value was found. That way you will only be doing a single lookup.

Wilco Bauwer

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Monday, December 12, 2005 10:15 AM

What timing, I was just looking into this same problem. Thanks for the heads up.

Bill

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Monday, December 12, 2005 10:24 AM

Thanks Wilco, that's indeed another way to do it and even more efficient, I'll add that to the post.

Frans Bouma

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Saturday, December 17, 2005 11:20 PM

This is another one of those cases where Microsoft is using Exception incorrectly, IMHO. A key not being in a collection should not be an 'exceptional' situation - it's quite common.

While the fix is easy enough this is not nearly as logical as checking for null on a result, especially given that there was precedent.

Lame to no end...

Rick Strahl

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Monday, December 19, 2005 9:36 AM

Well, was there anything wrong with the index operator returning null if the key was not found? Many lines of code rely on this behavior. A double check (if ContainsKey, then retrieve) introduces a potential race condition. Is it really an 'exceptional' condition for hashtable to have an empty slot?

Rafalg

# re: Dictionary<TKey, TValue> vs. Hashtable() tip@ Saturday, December 31, 2005 12:57 AM

The problem with returning null is that a generic collection can hold instances of value types or reference types, whereas a non-generic collection only holds instances of objects (reference type). Therefore, the non-generic collection can return null and the answer will still be semantically correct for the output type, whereas in a generic collection null cannot be assigned to a value type, so that would break compatability.

Perhaps MS could have supplied some kind of workaround that used nullable types when dealing with value types. I agree, this is certainly no place for an exception. Exceptions are supposed to be for exceptional circumstances! Major design flaw.

Adam Machanic