Option Types

Options are generic — OptionDefinition<T>. Built-in conversion is handled by OptionTypeMap for:

  • Any type implementing IConvertible: all numeric primitives (byte, sbyte, short, ushort, int, uint, long, ulong, float, double, decimal), char, bool, string, DateTime, and nullable variants of each
  • BCL types with dedicated parsers: nint, nuint, DateOnly, TimeOnly, DateTimeOffset, TimeSpan, Guid, and nullable variants of each

For any other type — arrays, enums, custom domain types — a Func<string, T> converter must be provided:

// Static default
cmdDef.AddOption<string>(
    key: "format", 
    defaultArg: "D", 
    help: "GUID format specifier.", 
    (terse: "-f", verbose: "--format")
);

// Dynamic default (evaluated at execution time)
cmdDef.AddOption<DateOnly>(
    key: "day", 
    defaultArg: (() => DateOnly.FromDateTime(DateTime.Now), "Current date."), 
    help: "Date of time entry.", 
    (terse: "-d", verbose: "--day")
);

// Terse flag omitted (verbose is required, terse is optional)
cmdDef.AddOption<string>(
    key: "period", 
    defaultArg: "all", 
    help: "Snapshot period filter.", 
    (terse: null, verbose: "--period")
);

// Custom converter for arrays
Func<string, int[]> split = v =>
{
    var parts = v.Split(',', StringSplitOptions.RemoveEmptyEntries);
    var nums = new int[parts.Length];
    for (int i = 0; i < parts.Length; i++)
        nums[i] = OptionTypeMap.ParseOptionArgument<int>(parts[i]);
    return nums;
};
cmdDef.AddOption<int[]>(
    key: "values", 
    help: "Comma-delimited integers.", 
    split, 
    (terse: "-v", verbose: "--values")
);

// Custom converter for enums
cmdDef.AddOption<FileMode>(
    key: "mode", 
    help: "File open mode.", 
    arg => Enum.Parse<FileMode>(arg, true), 
    (terse: "-m", verbose: "--mode")
);