在不广泛使用If-Else语句的情况下创建基于命令的应用程序

时间:2016-09-01 00:06:56

标签: c#

我想要使用这个C#应用程序。它主要是基于命令的,我的意思是用户输入某种类型的命令,应用程序只是执行某种任务。

例如:用户可以键入getdate等命令,应用程序会读取此命令并只显示日期。

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

有没有办法可以做到这一点,或者我只需要使用一些长的if-else语句。

5 个答案:

答案 0 :(得分:3)

您可以选择几个选项:

  • 您可以拥有映射到要初始化的类型的命令。

    Dictionary<string, Type>类型映射到您初始化的类。

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

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

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

答案 1 :(得分:2)

使用一种简单形式的Command Pattern以及某种Command Collection。

构建它的一个简单方法是:

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();
    }
}

答案 2 :(得分:2)

使用委托:

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);
    }
}

答案 3 :(得分:1)

您可以使用使用string作为键和方法(Action,Func或自定义委托)作为值的字典,然后您只需要从用户那里获取输入并使用密钥来得到相应的行动。如果该命令可以包含此command param1之类的参数,则使用string.Split将命令与参数分开,然后使用命令字符串作为键,并在执行该方法时将另一个字符串作为参数传递(取决于参数的数据类型可能需要将命令的参数从字符串解析为其他东西)

代码如下所示:

使用Func:

注意: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;
}

答案 4 :(得分:0)

您可以使用switch,或者您可以创建一个以问题为键,命令为值的词典。建议您对键和输入执行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
    }
}
}