Sometimes you need a flag that can be used in three ways: not present, present without a value (using a default), or present with an explicit value. The FlagValue<T> type handles this pattern cleanly.
What We're Building
The --port flag used three ways: omitted entirely, present without a value (uses default 3000), or with an explicit value like --port 8080:
Define a Flag Value
Use FlagValue<T> with square brackets in the template to indicate the value is optional. When users specify --port without a value, the flag is set but uses the type's default. When they specify --port 8080, the flag is set with that value.
public class Settings : CommandSettings
{
[CommandOption("--port [PORT]")]
[Description("The port to listen on (default: 3000 if flag present)")]
[DefaultValue(3000)]
public required FlagValue<int> Port { get; init; }
[CommandOption("--timeout [SECONDS]")]
[Description("Connection timeout in seconds")]
public required FlagValue<int?> Timeout { get; init; }
[CommandOption("-h|--host")]
[Description("The host to bind to")]
[DefaultValue("localhost")]
public required string Host { get; init; } = "localhost";
}
This produces the following usage:
USAGE:
myapp [OPTIONS]
OPTIONS:
--port [PORT] The port to listen on (default: 3000 if flag present)
--timeout [SECONDS] Connection timeout in seconds
-h, --host The host to bind to [default: localhost]
Check if a Flag Was Provided
The FlagValue<T> type has two properties: IsSet indicates whether the flag was present on the command line, and Value contains the parsed value (or the type's default if no value was given).
System.Console.WriteLine($"Host: {settings.Host}");
// Check if --port flag was provided
if (settings.Port.IsSet)
{
System.Console.WriteLine($"Port: {settings.Port.Value}");
}
else
{
System.Console.WriteLine("Port: not specified (will use system default)");
}
// Check if --timeout flag was provided
if (settings.Timeout is { IsSet: true, Value: not null })
{
System.Console.WriteLine($"Timeout: {settings.Timeout.Value} seconds");
}
else if (settings.Timeout.IsSet)
{
System.Console.WriteLine($"Timeout: system default seconds");
}
else
{
System.Console.WriteLine("Timeout: disabled");
}
return 0;
This lets you distinguish between:
myapp— flag not present (IsSetis false)myapp --port— flag present without value (IsSetis true,Valueis 0)myapp --port 8080— flag present with value (IsSetis true,Valueis 8080)
See Also
- Defining Commands and Arguments - Basic argument and option patterns
- Making Options Required - Making options required