Consider the following code
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
namespace zzCmdLineTest
{
class Program
{
static void Main(string[] args)
{
var command = new RootCommand
{
new Option<string>("--a-string", getDefaultValue: () => "goodbye"),
new Option<int>("--an-int")
};
command.Handler = CommandHandler.Create(
(string aString, int anInt) =>
{
Console.WriteLine(aString);
Console.WriteLine(anInt);
});
command.InvokeAsync(args);
}
}
}
Building, running and parsing gives the expected results with the default string value
C:\Code\zzCmdLineTest>dotnet run [parse]
[ zzCmdLineTest *[ --a-string <goodbye> ] ]
C:\Code\zzCmdLineTest>dotnet run
goodbye
0
Now change the code to add an Arity on the string parameter like this
var command = new RootCommand
{
new Option<string>("--a-string", getDefaultValue: () => "goodbye")
{ Argument = new Argument<string>() { Arity = ArgumentArity.ZeroOrOne }},
new Option<int>("--an-int")
};
Building, running and parsing shows that the default value for the string variable no longer applies
C:\Code\zzCmdLineTest>dotnet run [parse]
[ zzCmdLineTest ]
C:\Code\zzCmdLineTest>dotnet run
0
I would expect the default value to remain in tact whether or not I had explicitly set that the Option was optional.
This is a design flaw that can possibly be avoided by removing the Option.Argument property so that when you need to customize it, you're not replacing the instance. We would then have something like:
new Option<string>("--a-string", getDefaultValue: () => "goodbye")
{
Arity = ArgumentArity.ZeroOrOne
}
Thoughts?
Having the Arity property on the Option class makes more sense to me. It's actually how I assumed it worked before I looked into the docs properly, so I would be all for this change.
Most helpful comment
This is a design flaw that can possibly be avoided by removing the
Option.Argumentproperty so that when you need to customize it, you're not replacing the instance. We would then have something like:Thoughts?