创建一个基于命令的应用程序,而不需要大量使用If-Else语句

本文关键字:不需要 语句 If-Else 一个 于命令 创建 命令 应用程序 | 更新日期: 2023-09-27 18:04:56

我有这个c#应用程序,我想工作。它主要是基于命令的,我的意思是,用户输入某种类型的命令,应用程序简单地执行某种任务。

例如:用户可以输入一个命令,例如getdate,应用程序读取该命令并简单地显示日期。

注意:它将是基于控制台的,但我的问题是,实际的应用程序有大约80到100个命令,我的问题是如何读取这个命令,而不依赖于一些冗长的if-else语句来检查输入的命令。

我是否有办法做到这一点,或者我只能用一些长if-else语句。

创建一个基于命令的应用程序,而不需要大量使用If-Else语句

您可以采取以下几种选择:

  • 您可以有一个映射到要初始化的类型的命令目录。

    Dictionary<string, Type> Where type映射到初始化的类

  • 使用反射将命令直接映射到要初始化的对象(通过对象名称或属性)。

    [Command(Name = "update")]
    public class RunUpdates : ICommand {
    }
    [Command(Name = "restart")]
    public class RestartServer : ICommand {
    }
    

然后使用反射查找实现ICommand的对象,该对象具有与命令名称匹配的属性。

使用简单形式的命令模式和某种命令集合。

一个简单的方法是:
public class MyApp
{
    private readonly Dictionary<string, Action> _commands = new Dictionary<string, Action>();
    public static void Main()
    {
        var program = new MyApp();
        // Run Console Stuff
    }
    public MyApp()
    {
        SetupCommands();
    }
    public void SetupCommands()
    {
        _commands.Add("PrintDate", () => Console.WriteLine(DateTime.Now));
        _commands.Add("PrintMaxOf3And7", () => Console.WriteLine(Math.Max(3, 7)));
    }
    public void ExecuteCommand(string commandName)
    {
        _commands[commandName].Invoke();
    }
}

使用委托:

public delegate void CommandDelegate(string input);
public Dictionary<string, CommandDelegate> Commands { get; set; }
/// usage
public void InitCommands() 
{
    Commands.Add("showdata", (input) => Console.WriteLine(....));
    ... // other commands
}
public void ExecuteCommand(string userInput) 
{
    var firstWord = userInput.Substring(0, userInput.IndexOf(" "));
    if (Commands.ContainsKey(firstWord)) 
    {
         var command = Commands[firstWord];   
         command(userInput);
    }
}

您可以使用使用string作为键和方法(Action, Func或自定义委托)作为值的字典,然后您只需要读取来自用户的输入并使用它作为键键来获取相应的操作。如果命令可以有像command param1这样的参数,那么使用string.Split将命令与参数分开,然后使用命令字符串作为键,并且在执行方法时将另一个字符串作为参数传递(取决于参数的数据类型,可能需要将命令的参数从字符串解析为其他内容)

代码应该是这样的:

使用函数

:

注意:Func需要至少一个参数和一个返回值。

void Main()
{
    public Dictionary<string, Func<string, int>> commands =
                                   new Dictionary<string, Func<string, int>>();
    commands.Add("getdate", GetDate);
    Console.WriteLine("Enter a command");
    string input = Console.ReadLine(); //<-- Try typing "getdate"
    commands[input].Invoke();
}
public int GetDate(string someParameter)
{
   Console.WriteLine(DateTime.Today);
   return 0;
}
使用动作:

注意:Action至少需要一个参数。

void Main()
{
    public Dictionary<string, Action<string>> commands = new Dictionary<string, Action>();
    commands.Add("getdate", GetDate);
    Console.WriteLine("Enter a command");
    string input = Console.ReadLine(); //<-- Try typing "getdate"
    commands[input].Invoke();
}
public void GetDate(string someParameter)
{
   Console.WriteLine(DateTime.Today);
}

使用自定义委托:

public delegate double YourDelegate(string param);
void Main()
{
    public Dictionary<string, YourDelegate> commands = 
                                        new Dictionary<string, YourDelegate>();
    commands.Add("getdate", GetDate);
    Console.WriteLine("Enter a command");
    string input = Console.ReadLine(); //<-- Try typing "getdate"
    commands[input].Invoke();
}
public double GetDate(string someParameter)
{
   Console.WriteLine(DateTime.Today);
   return 0.0;
}

您可以使用switch,或者您可以创建一个Dictionary,其中question作为键,command作为值。建议对键和输入都使用ToLower(),使其不区分大小写,因为依赖用户完美地键入将是困难的。

private Dictionary<string,object> commandList = new Dictionary<string,object>();
private void processCommand(){
commandList.Add("showdate",DateTime.Now);
string command = Console.ReadLine();
if(command.Length>0){
    if(commandList.ContainsKey(command);
         object o = commandList[command.ToLower()];
         //do something
    }
}
}