Introduction
A switch-block becomes complex very easily. All code is placed in one method and parts of it are used multiple times. In a lot of cases, a switch-block is based on an enum
. Next to that, it's not possible to use a fall-through in C#. The only way to go from case to case is the use of the goto
statement, which isn't a good idea when reducing complexity. Although I've written the examples in C#, it wouldn't be hard to apply the principles to other languages.
A Solution
A nice solution to get rid of large switch constructions is the use of a Dictionary<enum,delegate>
. This way every element of the enum
can be attached to a method. It is possible to call the right method for every enum
possible. Because every enum
has its own method, it's very easy to use this construction in a testdriven environment. Another nice thing is that it's no problem to call one method from another. Let me explain a little further with an example and some pseudo code. Imagine a program that prepares food. This part contains the recipes.
Let us start with the following enum
:
Enum food{
Apple,
ApplePie,
AppleJuice,
Pizza
}
It's not hard to imagine that all of the foods need a specific preparation, but that some actions need to be done for different foods, like peeling an apple or baking in the oven.
To add the preparations to the Dictionary<enum, delegate>
, we first need to define a delegate
method:
delegate bool Preperation();
Now we need to define the actual preparation methods for every item of the enum
, making sure they're declared the same way as the delegate
, thus the same parameters and return value. The method returns a boolean when preparation is successful.
In this example, the methods may look something like this:
bool PeelApple()
{
return true;
}
bool BakePie()
{
PreheatOven(180.0);
PeelApple();
CreatePie();
while(!doneBaking())
Bake();
return true;
}
bool MakeAppleJuice()
{
PeelApple();
Juicify();
return true;
}
bool BakePizza()
{
PreheatOven(160.0);
CreatePizza();
while(!doneBaking())
Bake();
return true;
}
Notice that BakePie()
and MakeAppleJuice()
both call the method PeelApple()
. This is not possible in a switch
– case constructor, unless you call the methods from each case.
Now all that's left is to create and initialize the Dictionary
.
Dictionary<food, /> FoodPreperation;
..
FoodPreperation = new Dictionary<food, Preperation>();
FoodPreperation.add(food.Apple, new Preperation(PeelApple));
FoodPreperation.add(food.ApplePie, new Preperation(BakePie));
FoodPreperation.add(food.AppleJuice, new Preperation(MakeAppleJuice));
FoodPreperation.add(food.Pizza, new Preperation(BakePizza));
Calling the methods is done by:
food FoodOfChoice = food.ApplePie;
FoodPreperation[FoodOfChoice]();
In the last code snippet, the method that goes with food.ApplePie
is executed.
History
- 07 Oct 2008 - Initial upload
Microsoft MVP Client Dev . Founder of http://StoreAppsUG.nl, the Dutch Windows Store apps and Windows Phone apps usergroup. XAML / HTML5 developer. Writer. Composer. Musician.
Twitter
@Sorskoot
Awards / Honers
• October 2010,2011,2012,2013: Awarded Microsoft Expression Blend MVP
• June 2009: Second Place in the WinPHP challenge
• February 2009: Runner-up in de Mix09 10k Challenge
• June 2008: Winner of the Microsoft expression development contest at www.dekickoff.nl
Bio
I started programming around 1992, when my father had bought our first home computer. I used GWBasic at that time. After using QBasic and Pascal for a few years I started to learn C/C++ in 1996. I went to the ICT Academy in 1997 and finnished it in 2002. Until December 2007 I worked as a 3D specialist. Besides modelling I worked on different development projects like a 3D based Scheduler and different simultion tools in C# and Java. Though out the years I've gained much experience with ASP.NET, Silverlight, Windows Phone and WinRT.