Command Line Flags in C#

Command-line flags are a common way to specify options for command-line programs. For example, in wc -l the -l is a command-line flag.

C# provides various ways to handle command-line arguments. In this example, we’ll use the System.CommandLine library, which offers a more robust way to parse command-line arguments similar to Go’s flag package.

First, you need to install the System.CommandLine NuGet package. You can do this via the command line:

dotnet add package System.CommandLine --version 2.0.0-beta4.22272.1

Now, let’s implement our example command-line program:

using System;
using System.CommandLine;

class Program
{
    static async Task<int> Main(string[] args)
    {
        // Basic option declarations are available for string,
        // integer, and boolean options. Here we declare a
        // string option 'word' with a default value "foo"
        // and a short description.
        var wordOption = new Option<string>(
            "--word",
            getDefaultValue: () => "foo",
            description: "a string");

        // This declares 'numb' and 'fork' options, using a
        // similar approach to the 'word' option.
        var numbOption = new Option<int>(
            "--numb",
            getDefaultValue: () => 42,
            description: "an int");

        var forkOption = new Option<bool>(
            "--fork",
            getDefaultValue: () => false,
            description: "a bool");

        // It's also possible to declare an option that uses an
        // existing var declared elsewhere in the program.
        string svar = "bar";
        var svarOption = new Option<string>(
            "--svar",
            getDefaultValue: () => svar,
            description: "a string var");

        // Create a root command and add options
        var rootCommand = new RootCommand("Command-line flags example");
        rootCommand.AddOption(wordOption);
        rootCommand.AddOption(numbOption);
        rootCommand.AddOption(forkOption);
        rootCommand.AddOption(svarOption);

        rootCommand.SetHandler((string word, int numb, bool fork, string svarValue) =>
        {
            Console.WriteLine($"word: {word}");
            Console.WriteLine($"numb: {numb}");
            Console.WriteLine($"fork: {fork}");
            Console.WriteLine($"svar: {svarValue}");
            Console.WriteLine($"tail: [{string.Join(", ", args)}]");
        }, wordOption, numbOption, forkOption, svarOption);

        return await rootCommand.InvokeAsync(args);
    }
}

To experiment with the command-line flags program, compile it and then run the resulting executable directly.

$ dotnet build
$ dotnet run -- -word=opt -numb=7 -fork -svar=flag
word: opt
numb: 7
fork: True
svar: flag
tail: [-word=opt, -numb=7, -fork, -svar=flag]

Note that if you omit flags, they automatically take their default values:

$ dotnet run -- -word=opt
word: opt
numb: 42
fork: False
svar: bar
tail: [-word=opt]

Trailing positional arguments can be provided after any flags:

$ dotnet run -- -word=opt a1 a2 a3
word: opt
numb: 42
fork: False
svar: bar
tail: [-word=opt, a1, a2, a3]

Use -h or --help flags to get automatically generated help text for the command-line program:

$ dotnet run -- -h
Description:
  Command-line flags example

Usage:
  ConsoleApp [options]

Options:
  --word <word>    a string [default: foo]
  --numb <numb>    an int [default: 42]
  --fork           a bool
  --svar <svar>    a string var [default: bar]
  --version        Show version information
  -?, -h, --help   Show help and usage information

If you provide an option that wasn’t specified, the program will print an error message and show the help text again.

The System.CommandLine library in C# provides a more structured way to handle command-line arguments compared to manually parsing args. It offers features like automatic help generation, type parsing, and default values, making it a powerful tool for creating command-line applications in C#.