Switch, select, case, really long if statement…whatever the cause, when they get too long they all become unmanageable.  Overly long switch statements do exists, I’ve written them, we have all seen them in other peoples code.  In fact, I remember hearing, from a fellow Elegant Coder, that a coworker of his hit the limit for how many cases can be in a .Net switch statement.  I don’t remember what the limit was, but it was a lot, and they exceeded that number.

Side Note: what do you do in that situation?  Someone else wrote it, and is in a fix. In this case, the esteemed Elegant Coder smiled, said he had no idea, and walked away.

Now, what do you do if a switch statement slowly moves towards a maintenance nightmare?  After all, any switch statement, with more than 10 items in it will be larger than any screen output you have — thus moving beyond the ideal of being able to see all the code in a method without scrolling.

My solution: use a Dictionary.  Really, a Dictionary.  The keys are hashed, retrieval by index is very fast, and we have these cool delegate things and lambda to help us along.

First though:

Chris Brandsma’s rules of proper switch statement etiquette:

  1. A switch statement should really be in its own method, all by itself, away from all other innocent code.  I call this switch statement inoculation.
  2. There should be no more than one line of code in each case, not including the break;
  3. You should strive to use the return statement instead of relying on breaks.  This means that one line of code should return something.  If that is not the case…user the break.
  4. Best case, each case of a switch statement performs an action, and each action is in a separate class.

Following those three rules will better help you refactor switch statement code in the future.   But there are still a few reasons for not liking this. First off, switch statements are very static.  To add a new item to statement you have to recompile.  There are times when you would like the list to be a bit more dynamic.  Maybe you would like the list to be loaded via an IoC library. 

Now on to the refactoing…

Step 1: Figure out what each case statement needs to run.  Typically all the code in a case statement needs a common set of data to execute.  Figure out what that is.

Step 2:  Create a delegate for passing all of these values to each case as if it were a method.

Step 3: Convert all of the code in each case to a method that follows the delegate just created.

Step 4: Create a Dictionary that implements the delegate, and initialize the dictionary with the methods.

Step 5: Replace the switch with a single call to Invoke on the delegate.

Just show me some darn code

I’ve included a sample project, so you can just download it and check out the code from there.  I’ve included samples for .Net 2.0 (C# 2.0) and .Net 3.5 (C# 3.0) in the project.  I’m using .Net 3.5 code here.

For step one, here is a class that I created that contains all of the methods my switch/dictionary is going to call:

   1: public class ValueProcessor : IValueProcessor
   2: {
   3:     public string Chris(string data)
   4:     {
   5:         return "Brandsma" + data;
   6:     }
   8:     public string Jason(string data)
   9:     {
  10:         return "Grundy" + data;
  11:     }
  13:     public string Scott(string data)
  14:     {
  15:         return "Nickols" + data;
  16:     }
  18:     public string David(string data)
  19:     {
  20:         return "Starr" + data;
  21:     }
  23:     public string Tony(string data)
  24:     {
  25:         return "Rasa" + data;
  26:     }
  27: }

Also, my original switch statement looked like this:

   1: public string ReturnSomething(string name, string value)
   2: {
   3:     switch (name)
   4:     {
   5:         case "Chris":
   6:             return _valueProcessor.Chris(value);
   7:         case "David":
   8:             return _valueProcessor.David(value);
   9:         case "Scott":
  10:             return _valueProcessor.Scott(value);
  11:         case "Jason":
  12:             return _valueProcessor.Jason(value);
  13:         case "Tony":
  14:             return _valueProcessor.Tony(value);
  15:         default:
  16:             return string.Empty;
  17:     }
  18: }

Now the refactored version:

   1: public Dictionary<string, Func<string, string>> CreateDictionary()
   2: {
   3:     var dictionary = new Dictionary<string, Func<string, string>>
   4:                          {
   5:                              {"Chris", _valueProcessor.Chris},
   6:                              {"David", _valueProcessor.David},
   7:                              {"Jason", _valueProcessor.Jason},
   8:                              {"Scott", _valueProcessor.Scott},
   9:                              {"Tony", _valueProcessor.Tony}
  10:                          };
  11:     return dictionary;
  12: }
  14: public string ReturnSomething(string name, string value)
  15: {
  16:     if (_dictionary.ContainsKey(name))
  17:     {
  18:         return _dictionary[name].Invoke(value);
  19:     }
  20:     return string.Empty;
  21: }

When to do this

Something I’ll point out right away, there is more code in the refactored version.  But removing code is not always what we are after, we are after maintainable code.  For the purposes of this demo, I kept things simple, we were not dealing with a large switch statement to begin with.

If you go through the switch statement rules above and you still need something else, then bring this out.  But, I do not see this as an automatic way to upgrade some code.

Next Steps

That is the thing with refactoring, you are never really done.  You can move the dictionary initialization to its own class.  Or you can replace the dictionary with an IoC.  Depends on what you need.

Sample Project Download

Previous post

Introducing the Butters’ Monthly Bone

Next post

Ethics in Software Development: Craftsmanship over Crap


  1. January 12, 2009 at 11:31 am

    I’ve allready done this approach in a small project. Have you meassured the performance ?

  2. January 12, 2009 at 4:52 pm

    I just created a switch statement with 5,000 items (I tried more but Visual Studio kept crashing). This coworker must have been an idiot with a lot of time on his hands.

  3. January 16, 2009 at 11:46 am

    I agree with JP, refactoring to patterns would point you to polymorphism.

  4. January 26, 2009 at 5:16 pm

    Problem is we have aroung 1500 switch cases in our controller is there anything we can do to refator

  5. January 31, 2009 at 3:44 am

    […] In her book, Relevance and Linguistic Meaning: The Semantics and Pragmatics of Discourse Markers, Diane Blakemore speaks, among other things, of incoherent interpretation and contextual assumptions.  While pondering these phrases, I was reminded of Chris Brandsma’s recent article on Refactoring a switch statement. […]

  6. February 8, 2009 at 11:08 am

    I’ve used this pattern too, sometimes I’ll have a domain factory class that produces little strategy objects based on some criteria. Hate using IoC in such a situation and this solution works a treat.

  7. February 23, 2009 at 2:30 pm

    Hey thanks for this, I really like it I actually have some questions…

    Should we EVER use a switch statement?

    The only time I consider using them is when I know the code is final and that code is sitting on the very top layer almost like a script.

    In my last job I was “set straight” that case statements were in fact the only way to do certain things which at the time I strongly disagreed with. For instance type checking & do such and such if its this type etc. I took it quite hard that my efforts to aim for elegance were put down and dismissed and I had to have those ideas knocked out of me! I’m still very bitter by the whole experience.

    I wonder what stands in the way of these ideals, and why we have things such as case statements?