Skip to content

The [DefaultValue] attribute does not support arrays #1163

@0xced

Description

@0xced

Information

  • OS: Any
  • Version: Spectre.Console.Cli 0.46.0
  • Terminal: Any

Describe the bug
The [DefaultValue] attribute does not support arrays.

To Reproduce
Run the following program (without passing any arguments):

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using Spectre.Console;
using Spectre.Console.Cli;

var app = new CommandApp<DefaultCommand>();
app.Configure(config => config.PropagateExceptions());
app.Run(args);

internal class DefaultCommand : Command<DefaultCommand.Settings>
{
    internal class Settings : CommandSettings
    {
        [CommandOption("--arch <architecture>")]
        [DefaultValue(new[] { Architecture.X64, Architecture.Arm64 })]
        public Architecture[] Architectures { get; init; } = Array.Empty<Architecture>();
    }

    public override int Execute(CommandContext context,Settings settings)
    {
        AnsiConsole.WriteLine($"{settings.Architectures.Length} architectures: {string.Join(", ", settings.Architectures)}");
        return 0;
    }
}

Expected behavior
The following output should be printed on the console:

2 architectures: X64, Arm64

And when running with the --help option, the default values should be properly displayed:

OPTIONS:
                                 DEFAULT
    -h, --help                                 Prints help information
        --arch <ARCHITECTURE>    X64, Arm64

Actual behavior

When running without any arguments an InvalidCastException exception is thrown:

Unhandled exception. System.InvalidCastException: Object cannot be stored in an array of this type.
   at System.Array.InternalSetValue(Object value, IntPtr flattenedIndex)
   at System.Array.SetValue(Object value, Int32 index)
   at Spectre.Console.Cli.CommandValueBinder.GetArray(CommandParameter parameter, Object value) in /_/src/Spectre.Console.Cli/Internal/Binding/CommandValueBinder.cs:line 88
   at Spectre.Console.Cli.CommandValueBinder.Bind(CommandParameter parameter, ITypeResolver resolver, Object value) in /_/src/Spectre.Console.Cli/Internal/Binding/CommandValueBinder.cs:line 20
   at Spectre.Console.Cli.CommandValueResolver.GetParameterValues(CommandTree tree, ITypeResolver resolver) in /_/src/Spectre.Console.Cli/Internal/Binding/CommandValueResolver.cs:line 45
   at Spectre.Console.Cli.CommandBinder.Bind(CommandTree tree, Type settingsType, ITypeResolver resolver) in /_/src/Spectre.Console.Cli/Internal/CommandBinder.cs:line 7
   at Spectre.Console.Cli.CommandExecutor.Execute(CommandTree leaf, CommandTree tree, CommandContext context, ITypeResolver resolver, IConfiguration configuration) in /_/src/Spectre.Console.Cli/Internal/CommandExecutor.cs:line 105
   at Spectre.Console.Cli.CommandExecutor.Execute(IConfiguration configuration, IEnumerable`1 args) in /_/src/Spectre.Console.Cli/Internal/CommandExecutor.cs:line 86
   at Spectre.Console.Cli.CommandApp.RunAsync(IEnumerable`1 args) in /_/src/Spectre.Console.Cli/CommandApp.cs:line 81
   at Spectre.Console.Cli.CommandApp.Run(IEnumerable`1 args) in /_/src/Spectre.Console.Cli/CommandApp.cs:line 55
   at Spectre.Console.Cli.CommandApp`1.Run(IEnumerable`1 args) in /_/src/Spectre.Console.Cli/CommandAppOfT.cs:line 38
   at Program.<Main>$(String[] args) in Program.cs:line 9

When running with the --help option the default value is useless:

OPTIONS:
                                 DEFAULT                                                                 
    -h, --help                                                                    Prints help information
        --arch <ARCHITECTURE>    System.Runtime.InteropServices.Architecture[] 

Additional context
A pull request is coming soon to address this issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs triageSomeone needs to take a look at this

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions