如何解析和执行命令行样式字符串?

时间:2011-06-04 07:08:56

标签: c# .net asp.net-mvc object methods

4 个答案:

答案 0 :(得分:5)

查看 Mono.Options 。它目前是Mono框架的一部分,但可以下载并用作单个库。

您可以obtain it here,也可以grab the current version used in Mono as a single file

string data = null;
bool help   = false;
int verbose = 0;
var p = new OptionSet () {
    { "file=",      v => data = v },
    { "v|verbose",  v => { ++verbose } },
    { "h|?|help",   v => help = v != null },
};
List<string> extra = p.Parse (args);

答案 1 :(得分:4)

我通常使用的解决方案看起来像这样。请忽略我的语法错误......自从我使用C#以来已经过了几个月。基本上,用System.Collections.Generic.Dictionary<string, /* Blah Blah */>查找和虚函数调用替换if / else /开关。

interface ICommand
{
    string Name { get; }
    void Invoke();
}

//Example commands
class Edit : ICommand
{
    string Name { get { return "edit"; } }
    void Invoke()
    {
        //Do whatever you need to do for the edit command
    }
}

class Delete : ICommand
{
    string Name { get { return "delete"; } }
    void Invoke()
    {
        //Do whatever you need to do for the delete command
    }
}

class CommandParser
{
    private Dictionary<string, ICommand> commands = new ...;

    public void AddCommand(ICommand cmd)
    {
        commands.Insert(cmd.Name, cmd);
    }

    public void Parse(string commandLine)
    {
        string[] args = SplitIntoArguments(commandLine); //Write that method yourself :)
        foreach(string arg in args)
        {
            ICommand cmd = commands.Find(arg);
            if (!cmd)
            {
                throw new SyntaxError(String.Format("{0} is not a valid command.", arg));
            }
            cmd.Invoke();
        }
    }
}

class CommandParserXyz : CommandParser
{
    CommandParserXyz()
    {
        AddCommand(new Edit);
        AddCommand(new Delete);
    }
}

答案 2 :(得分:4)

请注意,您可以将参数放在可能使事物更具可读性的参数上,例如。

public void TOPIC (
    [ArgInfo("Specify topic ID...")] int Id, 
    [ArgInfo("Specify topic page...")] int? page) 
{
    ...
}

答案 3 :(得分:2)

我可以在这里看到两个不同的问题:

将方法名称(作为string)解析为命令模块

您可以使用Dictionary将字符串映射到方法,就像Billy的回答一样。如果您只希望方法优于命令对象,则可以直接在C#中将字符串映射到方法。

    static Dictionary<string, Action<List<string>>> commandMapper;

    static void Main(string[] args)
    {
        InitMapper();

        Invoke("TOPIC", new string[]{"1","2","3"}.ToList());
        Invoke("Topic", new string[] { "1", "2", "3" }.ToList());
        Invoke("Browse", new string[] { "1", "2", "3" }.ToList());
        Invoke("BadCommand", new string[] { "1", "2", "3" }.ToList());
    }

    private static void Invoke(string command, List<string> args)
    {
        command = command.ToLower();
        if (commandMapper.ContainsKey(command))
        {
            // Execute the method
            commandMapper[command](args);
        }
        else
        {
            // Command not found
            Console.WriteLine("{0} : Command not found!", command);
        }
    }

    private static void InitMapper()
    {
        // Add more command to the mapper here as you have more
        commandMapper = new Dictionary<string, Action<List<string>>>();
        commandMapper.Add("topic", Topic);
        commandMapper.Add("browse", Browse);
    }

    static void Topic(List<string> args)
    {
        // ..
        Console.WriteLine("Executing Topic");
    }

    static void Browse(List<string> args)
    {
        // ..
        Console.WriteLine("Executing Browse");
    }

解析命令行参数

早期人们一直在摸索着解决这个问题。

但是现在我们有专门处理这个问题的库。请参阅http://tirania.org/blog/archive/2008/Oct-14.htmlNDesk.Options。这应该更容易,并且可以处理一些陷阱案例而不是推出新的案例。