CommandLineParser 只应允许其中一个参数

Only one of arguments should be allowed with CommandLineParser

我正在开发一个控制台工具,它接受一些参数,然后解析为 Option class.

我需要的是一个 属性,它将验证 选项 class 中的许多标记字段是否只有一个有值(参数已传递)。

例如。 当我们 运行:

没问题

my.exe-a

my.exe-b

但不是:

my.exe

my.exe -a -b

CommandLine.OptionAttribute不能做这样的事。我所做的是: Main class args[] 得到了扩展名 .Parse:

args.Parse(options)` //where options is my Options class

里面:

CommandLine.Parser.Default.ParseArguments(args, options);
var isOnlyOneOfMany = options.GetType().GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(OneOfMany)) && prop.GetValue(options) != null).Count() == 1;

如何更好地做到这一点?

我会改写你的Optionsclass

class Options
{
    public int OneOfManyCount { get; private set;}

    // This is not OneOfMany
    [Option('n', "name", Required = true)]
    public string Name { get; set; }

    private string _Value;
    [OneOfMany]
    [Option('v', "value", Required = true)]
    public string Value { get { return _Value; } set { _Value = value; OneOfManyCount++;} }

    private string _Date;
    [OneOfMany]
    [Option('d', "data", Required = true)]
    public string Data { get { return _Date; } set { _Date = value; OneOfManyCount++;} }
}

并且在您的 main 中,您可以调用 options.OneOfManyCount 来获取参数的数量

    CommandLine.Parser.Default.ParseArguments(args, options);
    if(options.OneOfManyCount != 1) //Do something

请注意,如果你们中的一个 OneOfManyDefaultValue 属性,它会再次击中 set,这意味着 OneOfManyCount 会有意想不到的结果值。

更新:此解决方案不适用于 2.8.0 版,因为选项

中不允许同时使用 SetName 和 Group

您可以使用 SetNameGroupName 来实现此行为:

GroupName:从版本 2.7+

开始可用

An option group represents a group of options which are optional, but at least one should be available.

SetName:1.9+

版本可用

It means that you can run commands of one set at a time. You can't mix commands of more than one set otherwise you get an error.

新选项class:

public class Options
{
    [Option('a', "aValue", Group = "Values", SetName = "ASet")]
    public bool AValue { get; set; }

    [Option('b', "aValue", Group = "Values", SetName = "BSet")]
    public bool BValue { get; set; }
}

如何解析参数:

var options = Parser.Default.ParseArguments<Options>(args);