Making Switch Refactorings Better – Defaultable Dictionary
I’ve written before on the idea of refactoring a switch to a Map or Dictionary.
There is one major problem that I have been running into though. Switch statements and dictionaries are not functionally equivalent for one major reason…
Switches allow for default
I kept struggling with this when I would implement a dictionary to replace a switch. How can I deal with the default case?
There are of course many ways to deal with the default case in a dictionary or map, but I didn’t really like any of the solutions because they either required me to remember to check to see if my entry was in the dictionary before looking it up, or to rely on catching an exception.
Let me give you an example:
Converting this to a dictionary we get something like:
So clunky, just to handle the default case.
Would be much better do something like this:
Well now you can!
Also the first thing I ever put on GitHub!
The idea is pretty simple, I am just creating a decorator for IDictionary.
The DefaultableDictionary has a constructor that takes an IDictionary and a default value.
It then delegates all of the methods to the passed in IDictionary reference. For the methods that look up a value, it handles returning the default if the key doesn’t exist in the dictionary.
I created an extension method that lets you just put a .WithDefaultValue() on the end of your dictionary declaration in order to auto-magically give you a DefaultableDictionary back with that default value.
Sleep well my friend
Knowing that you can not create a dictionary that has a default value which is returned instead of throwing an exception if the key passed in is not found.
I have no doubt that in 3rd world countries children are still starving, but in 1st world countries children with VS Express hacking away at iPhone applications using MonoTouch will not have to catch exceptions from dictionaries that do not know how to just return a default value.
So now there is no excuse! Refactor those switches!