22

I am writing a parser which calls some functions dependent on some value.

I can implement this logic with simple switch like this:

switch(some_val)   
{   
    case 0:   
        func0();   
        break;   
    case 1:   
        func1();   
        break;   
}     

or with delegates and a dictionary like this:

delegate void some_delegate();   
Dictionary<int, some_delegate> some_dictionary = new Dictionary<int, some_delegate>();   
some_dictionary[0] = func0;   
some_dictionary[1] = func1;   

some_dictionary[some_value].Invoke();    

Are these two methods equivalent and which is preferred?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Samvel Siradeghyan
  • 3,523
  • 3
  • 30
  • 49

6 Answers6

11

I strongly prefer the dictionary choice, because with an initializer, it can be a lot more compact and readable:

var actions = new Dictionary<int, Action>
{
  {1, () => Console.WriteLine("One!")},
  {2, () => Console.WriteLine("Two!")}
}

Also, you have some more flexibility; you can add conditions and actions programatically, which is often handy, depending on what you're doing.

  • 8
    It'll be slower than the switch. Be careful there, though; premature optimization is the root of all evil. Code for good design, readability, and all that jazz, and only work on the speed part if it's too slow for your purposes. The speed difference might be completely negligible, but the readability differences are real and obvious. –  May 24 '10 at 12:25
  • Thanks, time is not too critical for me in this case, so I will use Dectionary with delegate – Samvel Siradeghyan May 24 '10 at 12:45
9

In terms of access, they're identical: both just check if that specific value has a corresponding result. However, a Dictionary will throw an out-of-bounds exception if you try to access a non-existent key.

The choice should primarily be on re-usability. If you only need to make this branching logic at one point, then using a switch-case is probably makes more sense than storing a variable. If you need to access it repeatedly in separate points, then use the Dictionary to save yourself from just re-pasting the switch-statement repeatedly.

Grace Note
  • 3,205
  • 4
  • 35
  • 55
  • 5
    You could also use the old-school alternative to cut-and-paste programming. Put the switch statement into a method. – Waylon Flinn Aug 22 '11 at 20:14
7

If the typical programmer on your team is anything like the ones I often deal with, you should go for the simplest option i.e. the switch. The delegates seem to me like a 'clever' solution that is not needed.

Johann Strydom
  • 1,482
  • 14
  • 18
  • 1
    I agree with ccomet. If the switch only occurs once in your code, then its the best option, but if it gets duplicated on 2 or more methods, then the dictionary is the cleaner approach. Incompetent or disinterested programmers are a whole other problem. I don't believe it is beneficial to write "lowest common denominator" code. If the team is not interested in learning, then get a new job. ;) – Jacques Bosch Jul 09 '10 at 16:27
  • 1
    @Jacques Why not just refactor the switch statement into a method that gets called by both? – Waylon Flinn Aug 22 '11 at 20:11
4

I like the dictionary approach because it gives you the ability to possibly swap out your lambda expressions as the need arises. This is a great trick for a programmer to keep in their tool bag for cases involving programs using complex decision trees. It would be very unwieldy to modify your switch case blocks at run time and the best answer would end up involving lambdas anyway.

I once had a situation where I needed to create a switch statement dynamically. This method provided a lot more readable solution.

Zach Johnson
  • 682
  • 7
  • 14
2

Both do the same (well you should check if the key appears in the dictonary).

It is just a matter of readability. What looks the best for your and more important, what do people reading your code would prefer.

(I think the dictionary)

RvdK
  • 19,580
  • 4
  • 64
  • 107
0

If you need to switch on strings in a resource file, say for globalization purposes, then you'll need to use the dictionary/delegate approach.

Nathan Dace
  • 1,545
  • 9
  • 21