Exxili
Exxili

Reputation: 45

How to refactor a switch case?

How to refactor a large switch case statement that changes via a Console.Readline string?

I have read up multiple websites and Stack Overflow posts regarding this but still do not seem to understand nor know if this is the correct way. Still fairly new to c#.

I have a Console.ReadLine which accepts user Input, I also have a switch case which switches based on the User input

string cmd = Console.ReadLine();

switch(cmd) {
case "login":
    //Execute Login Logic here
    break;

case "logout": 
    //Execute Logout logic here
    break;

//etc.etc.
}

I'm expecting there is some better way to refactor this to stop me needing a larger and larger switch case statement, I have been reading about conditional polymorphism although I am unsure if this is correct, Could someone help me to better understand how i would accomplish this?

Upvotes: 0

Views: 1870

Answers (4)

Tim Schmelter
Tim Schmelter

Reputation: 460098

Well, you could store all possible commands in a collection. You also might want to compare in a case insensitive way:

Dictionary<string, Action> Commands = new Dictionary<string, Action>(StringComparer.InvariantCultureIgnoreCase)
        { { "login", Login }, { "logout", Logout } };

void Login()
{
    // your logic...
}
void Logout()
{
    // your logic...
}

Action GetCommand(string commandName)
{
    return Commands.TryGetValue(commandName, out Action action) ? action : null;
}

Now the code becomes concise and simple:

Action command = GetCommand(Console.ReadLine());
if (command != null)
{
    command();
}

If you need commands with a parameter you could store them in a Dictionary<string, Action<Object>>. If you need with different parameters you need multiple dictionaries:

private static readonly Dictionary<string, Action<object>> CommandWithParameter = new Dictionary<string, Action<object>>(StringComparer.InvariantCultureIgnoreCase)
    { { "login", Login }, { "logout", Logout } };

public static void Login(object parameter)
{
    // cast it to string or whatever here if necessary
}
public static void Logout(object parameter)
{
    // cast it to string or whatever here here if necessary
}

and then call it so:

Action<object> command = GetCommand(cmd);
if (command != null)
{
    command(parameter);
}

Upvotes: 2

Antonio Campagnaro
Antonio Campagnaro

Reputation: 558

IMO the better suitable pattern is the

strategy pattern

Theory, C# implementation

Upvotes: 0

AndyB
AndyB

Reputation: 101

You might want to consider using the chain of responsibility design pattern - https://www.dofactory.com/net/chain-of-responsibility-design-pattern Split the input into logical groups and use command handlers to process the input

Upvotes: 0

Hadi
Hadi

Reputation: 443

One of the best approach that you can do this kind of scenarios is Command Patten. you can see how to impelement this pattern from these links Command Design Pattern or Command Pattern

Upvotes: 2

Related Questions