-1

I want to be able to simplify my code for the future. So I was thinking that I could try using the name/value of a variable to figure out which method should be used, but I don't know the syntax for this if there is any. I wish to do this inside the type (i.e. as a part of the static class instead of an instance of the class, as answers to similar questions are only for instances of the class).

For example, I had the user input a string, and detect if the first word was found in a predefined list, like "help", "get", or "time". The first solution I thought of was having a big chain of conditionals to see if it matches.

public static void parsing(string userInput)
{
  //code for finding the value left out for brevity
  string firstWord = /*whatever is needed*/;
  
  switch(firstword)
  {
    //Command is the parent class
    case "help":
      Command.help(words[1..^1]);
      break;
    case "get":
      Command.get(words[1..^1]);
      break;
    //and so on
  }
}

However, I realized that this would get very tedious to maintain and to add or remove new instances from. I was wondering if there was a syntax in C# that would allow this. I know of an example in JS where this thing can be accomplished, it looks like the following:

class exampleClass {
    static getData() {
        return "someData"
    }

    static getData1() {
        return "otherData"
    }
    
    static allData(data) {
        return exampleClass[data]()
    }

}

Where exampleClass[data]() will be able to call that method inside of the class and allows for easier use. I would like to do something like this in my program, but I don't know the analog for it in C#. What should I do?

Alteria
  • 13
  • 4
  • Are you looking for [Call methods using names in C#](https://stackoverflow.com/q/6469027)? – dbc Jul 23 '23 at 00:28
  • To invoke a static method by name via reflection see [How to call static methods from name in string variable in C#?](https://stackoverflow.com/q/61289466) or [Calling a method on a static class given its type name and method names as strings](https://stackoverflow.com/q/1418209). Does that answer your question? – dbc Jul 23 '23 at 03:32
  • Let's hope nobody passes data equal to `"constructor"` or `"propertyIsEnumerable"` (or even more scary `"__defineGetter__"`). – Raymond Chen Jul 26 '23 at 19:15

1 Answers1

1

You can use reflection for this, but reflection is kind of slow and I don't recommend it for this task.

Another approach is a switch statement like the one in your question. I know you've rejected this idea but switch statement can be pretty performant, and it wouldn't be that hard to maintain.

Finally, the way I like to handle this is to use a dictionary.

Dictionary<string, Action> CommandLookup = new(StringComparer.OrdinalIgnoreCase)
{
    ["help"] = help,
    ["get"] = get,
    // Etc....
};

public void RunCommand(string command)
{
    if (CommandLookup.TryGetValue(command, out Action action))
        action();
    else
        Console.WriteLine($"{command} is an unrecognized command.");
}
Jonathan Wood
  • 65,341
  • 71
  • 269
  • 466
  • How would you be able to implement this while also being able to pass in arguments? Asking for potential future use cases of the program. – Alteria Jul 24 '23 at 04:34
  • @Alteria: `Action` can be defined with arguments in the form `Action`. And you can even use `Func` if you need a return value. – Jonathan Wood Jul 24 '23 at 04:52