Category Archives: GitHub

Making Switch Refactorings Better – Defaultable Dictionary

I’ve written before on the idea of refactoring a switch to a Map or Dictionary.

English Dictionary Toolbar screenshot Making Switch Refactorings Better   Defaultable 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:

switch(vegetables)
{
	case Vegetables.Carrot:
		DoCarrotStuff();
		break;

	case Vegetables.Spinach:
		EatIt();
		break;

	case Vegetables.Peas:
		FeedToDog();
		break;

	default:
		Butter();
		Salt();
		SprinkleCheese();
		Eat();
}

Converting this to a dictionary we get something like:

var vegetableActionMap = new Dictionary<Vegetable, Action>
{
	{ Vegetable.Carrot, () => DoCarrotStuff() },
	{ Vegetable.Spinach, () => EatIt() },
	{ Vegetable.Peas, () => FeedToDog() }
}

Action result;
if(!vegetableActionMap.TryGetValue(vegetable, out result)
{
     Butter();
	  Salt();
     SprinkleCheese();
     Eat();
}
else
   result();

So clunky, just to handle the default case.

Would be much better do something like this:

var vegetableActionMap = new Dictionary<Vegetable, Action>
{
	{ Vegetable.Carrot, () => DoCarrotStuff() },
	{ Vegetable.Spinach, () => EatIt() },
	{ Vegetable.Peas, () => FeedToDog() }
}.WithDefaultValue( () => { Butter(); Salt(); SprinkleCheese(); Eat(); });

vegetableActionMap[vegetable]();

Well now you can!

Enter DefaultableDictionary!

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.

unusual begging methods19 Making Switch Refactorings Better   Defaultable Dictionary

So now there is no excuse!  Refactor those switches!

As always, you can subscribe to this RSS feed to follow my posts on Making the Complex Simple.  Feel free to check out ElegantCode.com where I post about the topic of writing elegant code about once a week.  Also, you can follow me on twitter here.