This describes yet another way to do things. Suppose you have input coming from a common source, but based on the content of that input, you want your program to do different things. Naturally, the first thing you think of is the switch statement. But I've stumbled across an interesting alternative.
Here is a simplified class in C# that uses a switch statement:
public class MyGame: IGame { public string ExecuteCommand(string command, string parameter) { string result; switch (command) { case "ECHO": result = DoEcho(parameters); break; case "JOIN": result = DoJoin(parameters); break; case "READY": result = DoReady(parameters); break; default: result = DoError(); break: } return result; } public string DoEcho(string parameters) { string result; // code here return result; } public string DoJoin(string parameters) { string result; // code here return result; } public string DoReady(string parameters) { string result; // code here return result; } public string DoError() { string result; // code here return result; }}
I decided to play around with generics to see if I could come up with an alternative to "switch". By using a Dictionary of delegates, I can look up what the appropriate action to take would be, and then do it in a generic fashion.
public class MyGame: IGame { private delegate string CommandHandler(string parameters); protected Dictionary<string, CommandHandler> commandHandlers = new Dictionary<string, CommandHandler>(); public MyGame() { commandHandlers["ECHO"] = new CommandHandler(DoEcho); commandHandlers["JOIN"] = new CommandHandler(DoJoin); commandHandlers["READY"] = new CommandHandler(DoReady); } public string ExecuteCommand(string command, string parameter) { CommandHandler handler; if (commandHandlers.TryGetValue(command, out handler)) { return handler.Invoke(parameter); } else { return DoError(); } } // handler code is same above. }
I don't know about you, but this is much more satisfying at varying levels. I've never liked the switch statement syntax, ever, and this code is easier on the eyes. This transforms the dispatch mechanism from a procedural approach to a table-driven approach. The one disadvantage is that all the dispatch methods must have the same figure, but usually uniformity is a welcome attribute to code. One cool thing is that by adding a new handler, Resharper will automagically generate the signature for the new dispatch method.
A place where this approach might be useful is by assigning abstract factory methods as delegates. Those have to be uniform, by design contract.
One thing I would like to see is the ability to assign all of the elements in the dictionary in a single statement. I understand this will be a new feature in C# 3.0, but I haven't experimented with that yet. I just downloaded the SDK yesterday!
Remember Me
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.