Search code examples
c#consolestring-parsingflow-control

In C#, what is the best way to control flow based on parsing an input string


I'm building a console application to help expidite some stuff I do regularly. I have a menu with 4 options of procedures, which translate to different methods in my class.

Basicaly it's kind of like this:

What do you want to do?

1 This Thing

2 That Thing

3 Some Stuff

4 Cool Stuff

0 All The Stuff.

Input command string:_

Currently I'm checking for valid input with:

while (command.IndexOfAny("12340".ToCharArray()) == -1)
{
  //Display the menu and accept input
}

And then controlling flow with:

if (command.IndexOf("1") > 0 )
{
  thisThing();
}

if (command.IndexOf("2") > 0 )
{
  thatThing();
}

if (command.IndexOf("3") > 0 )
{
  someStuff();
}

if (command.IndexOf("4") > 0 )
{
  coolStuff();
}

if (command.IndexOf("0") > 0 )
{
  thisThing();
  thatThing();
  someStuff();
  coolStuff();
}

The goal is to provide input and run one or more processes as indicated:

1 : thisThing()

13 : thisThing() and someStuff();

42 : thatThing() and coolStuff();

0 : run all processes I have defined.

Is there a way to do something like this with better practices?


Solution

  • I would create an Dictionary<char, DoSomething>

    public delegate void DoSomething();
    
    Dictionary<char, DoSomething> commands = new Dictionary<char, DoThing>();
    commands.Add('0', new DoSomething(DoAll));
    commands.Add('1', new DoSomething(ThisThing));
    commands.Add('2', new DoSomething(ThatThing));
    commands.Add('3', new DoSomething(SomeStuff));
    commands.Add('4', new DoSomething(CoolStuff));
    

    Then, after input validation

    foreach(char c in command.ToCharArray()) 
    {  
       // Better check if the input is valid
       if(commands.ContainsKey(c))
           commands[c].Invoke();
    }
    

    The Dictionary contains, as keys, the chars allowed and, as values, the delegate to a function with void return and no arguments. Now it is just a matter of looping on the input char by char and invoke the associated method.

    Keep present that this approach, with so few choiches, is no better that a simple if/else if/else or switch/case. Also in this way, your user could type 24 or 42 inverting the order of execution of the methods and this could not be allowed in your real context.