views:

113

answers:

2

Hi there,

Long switch statments are often frowned upon. The solution is to use polymorphism. However what if the thing I'm switching on is not a type code? What I would like to do is replace the switch statement with something like this...

public void HandleString(string s = "Hello")
{
 ...
}

public void HandleString(string s = "Goodbye")
{
 ...
}

...
HandleString("Hello"); // results in the first method being called.

This would replace the following...

string s = "Hello";

switch(s)
{
   case "Hello":
   ...
   break;
   case "Goodbye":
   ...
   break;
   default;
   break;
}

Any ideas? In theory I think you could do away with 'if/switch' statements altogether and just call methods that are automatically bound based on the value of an expression.

+11  A: 

If you have a large number of options, and high possibility that there will be more in the future - or you just need to system to be easily extensible - then you can always use an explicit dispatch table:

Dictionary<string, Action<string>> actions =
    new Dictionary<string, Action<string>>()
    {
        { "Hello", HandleHello },
        { "Goodbye", HandleGoodbye }
    };

private static void HandleHello(string s) { ... }

private static void HandleGoodbye(string s) { ... }

...

actions[s](s);

You can also provide a way to extend the table by allowing external clients of your API to register their own handler for a given string.

Pavel Minaev
+1 exactly what I was going to say, but I type slower :-)
Greg Beech
Sure but I'd rather have the language implement it for me.
Ian Warburton
+1  A: 

There are languages that implement that sort of semantics. One that I'm familiar with is the compiler generator tool called Elegant from Phillips.

In a language like this, a simple factorial algorithm might look like:

fact (value : Int) : Int
    conditions value < 0
{
    { "Illegal input value\n" } astype Message
    return 0
}

fact (value = 0) : Int
{
    return 0
}

fact (value = 1) : Int
{
    return 1
}

fact (value : Int) : Int
{
    return value * fact(value - 1);
}
Richard Pennington
Common Lisp is a relatively well known language that lets one dispatch methods over specific values (as well as types, as is common elsewhere).
Pavel Minaev