在我们的控制台应用程序中,应用程序参数的解析是这样完成的:

using System.Linq;

namespace Generator
{
    internal class Program
    {
        public static void Main(string[] args)
        {
            var param1 = args.SingleOrDefault(arg => arg.StartsWith("p1:"));
            if (!string.IsNullOrEmpty(param1))
            {
                param1  = param1.Replace("p1:", "");
            }
            //...
        }
    }
}


应该这样称呼:


`Generator.exe p1:somevalue`



是否有更好/更简单的方法来解析参数?

评论

另外,FubuCore库具有一个功能强大且具有自文档说明功能的命令行args解析器,我在这里已对此进行了简要介绍

#1 楼

我建议利用出色的Mono.Options模块。这是一个.cs文件,您可以放入解决方案中并获得GNU getopt样式命令行的全功能解析。 (诸如-x -y -z之类的东西,等同于-xyz-k value--long-opt等)。

评论


\ $ \ begingroup \ $
从2018年开始:Microsoft在文件中添加了自己的代码。现在您不能将其用作单独的文件。谢谢女士。这是我发现的没有MS干预的最新标签
\ $ \ endgroup \ $
– maxkoryukov
18年4月13日在16:40

\ $ \ begingroup \ $
@maxkoryukov我不明白你的逻辑。它仍然是根据MIT许可获得许可的,该许可明确表明可以将其部分或全部复制,只要其中包含该许可即可。因此,截至2019年撰写本文时,您仍然可以自行获取此文件。除非您不合理地避免Microsoft曾经碰过的一切,否则您应该知道StackExchange在Microsoft软件上运行。
\ $ \ endgroup \ $
–莫妮卡基金的诉讼
19年1月12日在20:32



\ $ \ begingroup \ $
@NicHartley,您是对的,它仍然是MIT许可的。抱歉,但是我不记得当时的意思,所以现在不能解释我的评论了。是的,总体上,我不喜欢MS开发方式及其风格。但是我是谁)))
\ $ \ endgroup \ $
– maxkoryukov
19年1月14日在16:54

\ $ \ begingroup \ $
@maxkoryukov urgh,抱歉,我在这里的语气-我的确不是在讽刺,但重新阅读我的评论后,听起来确实像是在讽刺。是的,不喜欢微软是完全公平的。我的问题是,人们会避免接触过曾经接触过的一切,甚至因为某人成为了“污点”而间接地成为某人成为他们的开发者,并且(因为这一直是MIT许可的)我立即跳到了。我想我想像最坏的人。对不起:(
\ $ \ endgroup \ $
–莫妮卡基金的诉讼
19年1月14日在17:00

\ $ \ begingroup \ $
@NicHartley不要道歉;)我的评论有错误(并且仍然存在)—我无法以其他任何方式解释该评论。而且我不知道为什么要写那条评论。尽管有MS干预,但Mono.Options仍然是不错的C#代码
\ $ \ endgroup \ $
– maxkoryukov
19年1月14日在17:44

#2 楼

通过这样的实现,您将不得不为每个参数重复自己。

替代方法:

var parsedArgs = args
    .Select(s => s.Split(new[] {':'}, 1))
    .ToDictionary(s => s[0], s => s[1]);
string p1 = parsedArgs["p1"];


评论


\ $ \ begingroup \ $
+1:我会用'='。并检查参数是否以“-”为前缀。那么下一个参数不在同一参数中的值在哪里呢?
\ $ \ endgroup \ $
–马丁·约克
2011年1月28日在18:19

\ $ \ begingroup \ $
@Martin为什么要在参数前面加上'-'?
\ $ \ endgroup \ $
–疯狂
11年1月28日在18:38

\ $ \ begingroup \ $
@frennky:它是命令行参数(-或-)的一种标准。它将标志(修改行为)与输入/输出分开。但是,重新阅读您的原始问题后,我过于概括了,这不是您想要的。
\ $ \ endgroup \ $
–马丁·约克
11年1月28日在20:15



\ $ \ begingroup \ $
@frennky-我同意Martin的观点,如果您正在编写某个人(除了您之外)将使用的应用程序,那么您应该阅读有关控制台参数标准的知识。据我所知,“-”是一种* nix样式,在Windows中更多是关于斜杠。
\ $ \ endgroup \ $
–雪熊
2011年1月28日在20:22

#3 楼

堆栈溢出有一个相关的问题。那里的共识似乎是josh3736在此处建议的Mono.Options。

评论


\ $ \ begingroup \ $
进一步阅读该SO问题的答案列表,您将看到ndesk.org/Options的投票率是接受的答案的2倍。
\ $ \ endgroup \ $
–工匠
2011年3月4日17:00

\ $ \ begingroup \ $
实际上,您所指的答案是“我强烈建议使用NDesk.Options(文档)和/或Mono.Options(相同的API,不同的名称空间)。”
\ $ \ endgroup \ $
–唐·柯比(Don Kirkby)
2011年3月4日18:00

#4 楼

我通常不使用复杂的命令行参数,因此我使用非常简单的命令行参数解析器,但是它可以用作您自己的应用程序特定参数表示器的基础。

#5 楼

您可以使用foreach遍历参数,然后对于索引为1的参数,可以使用正则表达式来检索p1之后的解析文本:

评论


\ $ \ begingroup \ $
我希望避免使用循环。至于正则表达式,我认为这太多了,模式很简单。
\ $ \ endgroup \ $
–疯狂
11年1月28日在18:36

#6 楼

请从链接检查解决方案。 IT使用linq。我认为它简短且可重用。提供扩展方法,因此您只需执行以下操作即可:

args.Process(
           () => Console.WriteLine("Usage is switch1=value1,value2 switch2=value3"),
           new CommandLine.Switch("switch1",
               val => Console.WriteLine("switch 1 with value {0}",
                   string.Join(" ", val))),
           new CommandLine.Switch("switch2",
               val => Console.WriteLine("switch 2 with value {0}",
                   string.Join(" ", val)), "s1"));
   }


有关详细信息,请访问我的博客