C# - What is the best way to dispatch a bunch of functions all with the same signature?
1 22 Feb 2018 21:50 by u/aGameCalledCountries
C# is not my strongest language, but I am currently refactoring some spaghetti code placed in my lap.
I have a function similar to:
public static rpcCommand(string command, string arguments) {
switch(command) {
case "command1": {...blah...}
case "command2": {...blah...}
... goes on for about 150 commands and 2500 lines ...
}
}
I would like to refactor this into a separate function per command. In another language, I would have some global variable of map[string]RpcCommandFunction, or maybe a method per command and use reflection to discover if the command exists and execute it. What is the best approach in C#?
7 comments
0 u/roznak 23 Feb 2018 01:27
My experience with programming is that you can't predict what is the most efficient code. You need to try different ways and see which one works best for your problem.
So I propose to create a small program (Any language you desire ) to read in this source file and parses the function into a new C# source code that you then can test.
For speed, since the switch is a string, I would use some Dictionary collection so you can find fast look up the correct method/delegate/anonymous function for that command.
I use delegates the most: http://www.tutorialsteacher.com/csharp/csharp-delegates
0 u/aGameCalledCountries [OP] 23 Feb 2018 01:46
Performance wasn't the main concern with this problem. Breaking apart the 2500 line function was. I managed to solve the problem by creating a new class with static functions, then using the reflective GetMethod stuff. One thing I couldn't figure out with the dictionary of delegates route was where to put and instantiate the dictionary. Then there is the added problem of making sure all functions are in the dictionary for lookup. My way, if the method exists, it is callable.
0 u/roznak 23 Feb 2018 02:01
I am thinking you can use a (Sorted)Dictionary, to convert the string fast to a single value (int). Then stage 2 is use that (int) value/Enum in the switch to call your methods.
If speed is not an issue then your solution may be equally good.
The problem with GetMethod() is that if some other developer changes the method name, then you end up with a bug. The compiler won't warn you. And the other developer may not realize that your code that contains Getmethod() is a switch.
0 u/QuitWaistingOurMoney 23 Feb 2018 01:44
I don't work with it on a day to day basis so would need to look myself, but I think you could achieve what you are trying to do with C#'s Reflection capabilities.
Probably you can create a class to encapsulate all the various commands you have in separate methods named as their command name (maybe with an added constant like Command concatenated to it) then invoke it with reflection using the passed in name plus anything concatenated to it.
0 u/aGameCalledCountries [OP] 23 Feb 2018 01:51
That's what I ended up doing :)
0 u/QuitWaistingOurMoney 23 Feb 2018 01:56
Cool glad you got it worked out.
0 u/carlosomar2 27 Feb 2018 20:28
I think it looks like a good scenario for the command design pattern. http://www.dofactory.com/net/command-design-pattern