Command-line-api: Setting ArgumentArity on string Option disables Option's default value

Created on 5 Aug 2020  路  2Comments  路  Source: dotnet/command-line-api

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.

Area-API bug

Most helpful comment

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?

All 2 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

clmcgrath picture clmcgrath  路  3Comments

AlgorithmsAreCool picture AlgorithmsAreCool  路  6Comments

ibigbug picture ibigbug  路  3Comments

jonsequitur picture jonsequitur  路  4Comments

jnm2 picture jnm2  路  6Comments