【问题标题】:C# Framework With Command Line Interface带有命令行界面的 C# 框架
【发布时间】:2017-05-25 16:32:04
【问题描述】:

我想在 C# 控制台应用程序(CLI)中编写一个框架,细节并不重要。 我不知道如何干净、快速地识别命令。 我尝试使用 switch-case:

    public static void command_recognizing(string command) // random example
    {
        string[] tmp_array = command.Split(' ');
        switch(tmp_array[0])
        {
            case("help"):
                method_library.help(); // no need argument
                break;
            case("time"):
                method_library.time(); // no need argument
                break;
            case("shutdown"):
                method_library.shutdown(tmp_array); // need argument
                break;
            default:
                Console.WriteLine("Error! {0} is not a known command!",tmp_array[0]);
                break;
        }
    }

我也试过 if-else:

     public static void command_recognizing(string command) // random example
    {
        string[] tmp_array = command.Split(' ');
        if(command.Contains("help"))
        {
            method_library.help(); // no need argument
        }
        else if(command.Contains("time"))
        {
            method_library.time(); // no need argument
        }
        else if(command.Contains("shutdown"))
        {
            method_library.shutdown(tmp_array); // need argument
        }
        else
        {
            Console.WriteLine("Error! {0} is not a known command!",tmp_array[0]);
        }
    }

我尝试将命令存储在一个字符串数组中,还是一样,又长又丑。

还有其他方法可以让命令识别更短、更简洁、更容易修改吗? 请原谅我的英语。欢迎指正!

【问题讨论】:

  • 尝试谷歌搜索“c# 如何编写解释器”
  • Nuget > CommandLineParser
  • Peter Bons,我花了 1 周时间尝试编写一个普通的解析器。失败后,我花了3天时间搜索了一个,当然一无所获。大卫坦西这无济于事。 Nuget也不起作用。非常感谢 NetMage。

标签: c# command command-line-interface


【解决方案1】:

您可以使用反射来执行类的方法。

void Main() {
    var cmd = new Commands();

    while (!cmd.Exitting) {
        var cmdline = Console.ReadLine();
        var cmdargs = Regex.Split(cmdline.Trim(), @"\s+");
        if (!cmd.TryInvokeMember(cmdargs[0], cmdargs.Skip(1).ToArray()))
            Console.WriteLine($"Unknown command: {cmdargs[0]}");
    }
}

// Define other methods and classes here
public class Commands {
    public bool Exitting { get; private set; }

    public Commands() {
        Exitting = false;
    }

    public void exit() {
        Exitting = true;
    }

    public int sum(object[] args) {
        return args.Select(s => Convert.ToInt32(s)).Sum();
    }

    public bool TryInvokeMember(string methodName, object[] args) {
        var method = typeof(Commands).GetMethod(methodName.ToLower());

        if (method != null) {
            object res;
            if (method.GetParameters().Length > 0)
                res = method.Invoke(this, new object[] { args });
            else
                res = method.Invoke(this, new object[0]);

            if (method.ReturnType != typeof(void))
                Console.WriteLine(res.ToString());

            return true;
        }
        else
            return false;
    }
}

【讨论】:

  • NetMage 你太棒了,我写不下来,你的帮助有多大。这正是我想要的。
  • 感谢NetMage,我的框架开始增长,核心只有3000行代码(未准备好)。如果你不帮忙,核心应该是 4-5 千行代码。
  • 虽然我主要用 Perl 编写 CLI 程序(我编写 Cisco CLI 的前端来帮助我的工作),但为我创建 CLI 一直是我的爱好。很高兴它对您有所帮助。
猜你喜欢
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
  • 2011-09-29
  • 2011-05-29
  • 2021-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多