2

Im working on a console tool which accepts some arguments and then parses to the Option class.

What I need is a property that will verify if only one of many marked fields in Option class has values (arguments were delivered).

Ex. Its ok when we run:

my.exe -a

my.exe -b

but NOT:

my.exe

my.exe -a -b

CommandLine.OptionAttribute cannot do such a thing. What i did is: Main class args[] got extension .Parse:

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

inside:

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

how to do this better way?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236

2 Answers2

1

I will rewrite your Options class

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++;} }
}

and in your main, you can call options.OneOfManyCount to get the number of arguments

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

And please notice if you have a DefaultValue attribute on one of you OneOfMany, it will hit the set one more time which means OneOfManyCount will have unexpected value.

Liu
  • 970
  • 7
  • 19
0

Update: This solution doesn't work from version 2.8.0 because both SetName and Group are not allowed in option

You can use SetName and GroupName to achieve this behavior:

GroupName: Available from version 2.7+

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

SetName: Available from version 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.

The new option 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; }
}

How to parse the args:

var options = Parser.Default.ParseArguments<Options>(args);
itaiy
  • 1,152
  • 1
  • 13
  • 22
  • 1
    When I try to combine Group and SetName, I get this error: "Both SetName and Group are not allowed in option" – UnionP Nov 15 '20 at 17:09
  • 1
    As has been mentioned, you can't combine Group and SetName without getting the above error. This makes no sense as it should be possible to have a group, which will require one of the options, and a SetName to restrict it to only one of the options. For example, and add function and remove function. You should be able to require one but not both to be specified. The group would require one, and the SetName would restrict it to only one. – BardMorgan Dec 04 '20 at 17:55
  • 1
    @UnionP I've updated the answer. As you mentioned, form version 2.8 is not possible to use `Group` and `SetName` in the same `Option` – itaiy Dec 08 '20 at 14:26