0

I would like to code a framework in C# Console Application(CLI), details aren't important. I don't know, how to recognize commands cleanly, and shortly. I tried with 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;
        }
    }

I also tried 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]);
        }
    }

I tried to store the commands in a string array, still the same, long and ugly.

There is any other way, to make the command recognizing shorter, cleaner and easier to modify? Foregive me for my english. Feel free to correct me!

4
  • Try googling "c# how to write an interpreter" Commented May 25, 2017 at 16:45
  • Take a look at this post: stackoverflow.com/questions/673113/poor-mans-lexer-for-c-sharp Commented May 25, 2017 at 16:46
  • Nuget > CommandLineParser Commented May 25, 2017 at 17:14
  • Peter Bons, I spent 1 week to try to code a normal parser. After the failure, I spent 3 days to search one, of course nothing. David Tansey it could not help. Nuget also not work. Very big thanks to NetMage. Commented Jun 9, 2017 at 20:13

1 Answer 1

1

You could use Reflection to execute methods of a class.

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;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

NetMage you are awesome, I'm not able to write down, how big was your help. Exactly this is what I want.
Thanks to you NetMage, my framework started growing, the core only has 3000 lines of code(Not Ready). if you didn't help, the core should be 4-5 thousand of line of code.
While I mostly write my CLI programs in Perl (I write front ends to Cisco CLI to help my job), it has been a hobby to create CLIs for me. Glad it helped you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.