Skip to content

Value conversion

Adam Bajguz edited this page Dec 19, 2021 · 3 revisions

Parameters and options can have different underlying types:

  • Standard types
    • Primitive types (int, bool, double, ulong, char, etc.)
    • Date and time types (DateTime, DateTimeOffset, TimeSpan)
    • Enum types (converted from either name or value)
  • String-initializable types
    • Types with a constructor that accepts a single string parameter (FileInfo, DirectoryInfo, etc.)
    • Types with a static method Parse that accepts a single string parameter (and optionally IFormatProvider)
  • Nullable versions of all above types (decimal?, TimeSpan?, etc.)
  • Collections of all above types
    • Array types (T[])
    • Types that are assignable from arrays (IReadOnlyList<T>, ICollection<T>, etc.)
    • Types with a constructor that accepts a single T[] parameter (HashSet<T>, List<T>, etc.)

When targeting .NET 5 or above half is also supported.

When targeting .NET 6 or above DateOnly and TimeOnly are also supported.

When defining a parameter of an enumerable type, keep in mind that it has to be the only such parameter and it must be the last in order. Options, on the other hand, don't have this limitation.

Conversion of custom types is supported with Custom/Binding converters

Example command with an array-backed parameter:

[Command]
public class FileSizeCalculatorCommand : ICommand
{
    // FileInfo is string-initializable and IReadOnlyList<T> can be assgined from an array,
    // so the value of this property can be mapped from a sequence of arguments.
    [CommandParameter(0)]
    public IReadOnlyList<FileInfo> Files { get; set; }

    public ValueTask ExecuteAsync(IConsole console)
    {
        var totalSize = Files.Sum(f => f.Length);

        console.Output.WriteLine($"Total file size: {totalSize} bytes");

        return default;
    }
}
> myapp.exe file1.bin file2.exe

Total file size: 186368 bytes

Same command, but using an option for the list of files instead:

[Command]
public class FileSizeCalculatorCommand : ICommand
{
    [CommandOption("files")]
    public IReadOnlyList<FileInfo> Files { get; set; }

    public ValueTask ExecuteAsync(IConsole console)
    {
        var totalSize = Files.Sum(f => f.Length);

        console.Output.WriteLine($"Total file size: {totalSize} bytes");

        return default;
    }
}
> myapp.exe --files file1.bin file2.exe

Total file size: 186368 bytes
Clone this wiki locally