Keywords: C# | Command Line Arguments | NDesk.Options | Mono.Options | System.CommandLine
Abstract: This article provides an in-depth exploration of various methods for parsing command line arguments in C#, with a focus on the NDesk.Options and Mono.Options libraries. It compares other popular libraries such as Command Line Parser Library and System.CommandLine, detailing how to handle complex command line scenarios through pattern matching, regular expressions, and specialized libraries. Complete code examples and best practice recommendations are included to help developers build robust command line applications.
The Importance of Command Line Argument Parsing
In C# console application development, parsing command line arguments is a fundamental yet critical task. The traditional approach involves accessing the args array in the Main(string[] args) method and manually processing it through indexing and loops. However, as command line arguments become more complex, this simple method can lead to code that is difficult to maintain and extend. For instance, arguments may include flags, key-value pairs, positional parameters, and more, making manual parsing error-prone and inefficient.
Detailed Overview of NDesk.Options and Mono.Options
NDesk.Options and Mono.Options are two powerful command line parsing libraries with similar APIs, offering a declarative way to define and parse arguments. Below is a complete example demonstrating their usage:
bool show_help = false;
List<string> names = new List<string> ();
int repeat = 1;
var p = new OptionSet () {
{ "n|name=", "the {NAME} of someone to greet.",
v => names.Add (v) },
{ "r|repeat=",
"the number of {TIMES} to repeat the greeting.\n" +
"this must be an integer.",
(int v) => repeat = v },
{ "v", "increase debug message verbosity",
v => { if (v != null) ++verbosity; } },
{ "h|help", "show this message and exit",
v => show_help = v != null },
};
List<string> extra;
try {
extra = p.Parse (args);
}
catch (OptionException e) {
Console.Write ("greet: ");
Console.WriteLine (e.Message);
Console.WriteLine ("Try `greet --help' for more information.");
return;
}
In this example, the OptionSet class is used to define command line options. Each option can specify multiple aliases (e.g., "n|name=" for -n or --name) and is associated with a description and a callback function. The callback executes when the corresponding option is parsed, setting variables or performing logic. The library automatically handles parameter validation and error handling, such as throwing an OptionException for missing required parameters or type mismatches.
Alternative Approach with Command Line Parser Library
The Command Line Parser Library offers another declarative method based on attributes. By decorating class properties with attributes, command line arguments can be defined:
class Options
{
[Option("i", "input", Required = true, HelpText = "Input file to read.")]
public string InputFile { get; set; }
[Option(null, "length", HelpText = "The maximum number of bytes to process.")]
public int MaximumLenght { get; set; }
[Option("v", null, HelpText = "Print details during execution.")]
public bool Verbose { get; set; }
[HelpOption(HelpText = "Display this help screen.")]
public string GetUsage()
{
var usage = new StringBuilder();
usage.AppendLine("Quickstart Application 1.0");
usage.AppendLine("Read user manual for usage instructions...");
return usage.ToString();
}
}
This method uses reflection to automatically parse arguments and generate help information. Its advantages include cleaner code and easier maintenance, though it may have slight performance overhead.
Modern Approach with System.CommandLine
System.CommandLine is a newer library from Microsoft designed to simplify command line parsing. It supports various configuration methods, including method-based configuration:
public static void Main(FileInfo input, FileInfo output, int xCropSize = 0, int yCropSize = 0)
{
// Processing logic
}
With this approach, command line arguments are automatically mapped to the parameters of the Main method, eliminating the need for manual parsing. The library also provides advanced features like automatic help generation, version display, parameter validation, and tab completion.
Patterns and Best Practices
When handling command line arguments, the following patterns are recommended:
- Use libraries instead of manual parsing to improve code readability and maintainability.
- Provide clear descriptions and aliases for options to enhance user experience.
- Implement error handling to catch parsing exceptions and offer helpful error messages.
- Leverage automatic help features of libraries to reduce manual documentation maintenance.
Conclusion
Choosing the right command line parsing library can significantly boost development efficiency. NDesk.Options and Mono.Options are suitable for scenarios requiring flexible callbacks, Command Line Parser Library fits attribute-driven simple applications, and System.CommandLine offers the most modern solution with rich built-in features. Developers should select the appropriate tool based on project needs, follow best practices, and build robust command line applications.