JC.CommandLine 3.0.0

dotnet add package JC.CommandLine --version 3.0.0
                    
NuGet\Install-Package JC.CommandLine -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="JC.CommandLine" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="JC.CommandLine" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="JC.CommandLine" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add JC.CommandLine --version 3.0.0
                    
#r "nuget: JC.CommandLine, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package JC.CommandLine@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=JC.CommandLine&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=JC.CommandLine&version=3.0.0
                    
Install as a Cake Tool

John Cronan's Command Line Parser

This project is a flexible, feature-rich, well-tested command line parser implemented in 100% managed C#.

Philosophy

The parser is not attribute-based. Instead, command-line arguments and switches are defined and parsing options set via a builder (CommandLineParserBuilder), which is oriented toward simple, judicious use of method-chaining. Fully "fluent" syntax is specifically avoided.

Over-validation is specifically avoided. Consumers, it is assumed, will necessarily perform validation of their own anyway, so it doesn't make sense to write a lot of code to implement validation features that are very easy to do in consuming code.

Parsing and validation errors result in exceptions. It is the consumer's responsibility to handle them appropriately, e.g. displaying command usage text and potentially exiting prematurely. Parse warnings are exposed through the result returned by the Parse method, or by object binding (see below).

Usage

The package can be consumed one of three ways: By calling properties and methods of the ICommandLineParseResults instance returned from ICommandLineParser's Parse method; by property binding; or by constructor binding. Although property binding, being the expected most-common usage, is the default object binding, constructor binding is actually the recommended usage, as a command line is naturally immutable anyway.

Usage is simple: Create an instance of CommandLineParserBuilder, call its methods to set parse options and define arguments and switches, invoke the CreateParser method and, in turn, invoke Parse. Parse returns and instance of ICommandLineParseResults, which can then be used to Bind parse results to a newly-created object.

The object binders can bind (case insensitively) to arguments and properrties of most commonly used value types. Command line arguments with multiple values can be bound to a wide variety of collection types, including array, IEnumerable<T>, List<T>, IList<T>, ImmutableArray<T>, as well as their corresponding non-generic types.

Unnamed values are bound to arguments with the names "unnamedValues", "leadingUnnamedValues", and "trailingUnnamedValues". Parse warning are bound to a property named "parseWarnings".

The following command line:

Program.exe Import /Files authors.csv titles.csv publishers.csv /Batch-Size 1000 /S (local) /D Books /Verbose

May be defined and parsed by the following code:

var args =
	new CommandLineParserBuilder()
		.UseConstructorBinding()
		.AddArgument("Files", ArgumentMultiplicity.OneOrMore, true)
		.AddArgument("Batch-Size", ArgumentMultiplicity.One, false)
		.AddArgument("Server", ArgumentMultiplicity.One, false)
		.AddArgument("Database", ArgumentMultiplicity.One, true)
		.AddSwitch("Verbose")
		.CreateParser()
		.Parse()
		.Bind<CommandLine>();

And bound to a class with the following constructor:

internal class CommandLine
{
    public CommandLine(ImmutableArray<string> leadingUnnamedValues,
        ImmutableArray<string> files, int? batchSize, string server,
        string database, bool verbose)
    {                
    }
}

Or, if using property binding (with the UsePropertyBinding method):

internal class CommandLine
{
    public ImmutableArray<string> LeadingUnnamedValues { get; set; }
    public ImmutableArray<string> Files { get; set; }
    public int? BatchSize { get; set; }
    public string Server { get; set; }
    public string Database { get; set; }
    public bool Verbose { get; set; }
}

See the integration tests in the test folder at https://github.com/john-cronan/main for additional examples of usage.

Future Directions

Testing. The project could use more organized, thorough testing.

Binding errors and warnings. Currently, exceptions occurring during object binding are not handled ideally, especially type conversion errors. Revisions to allow the binders to contribute errors and warnings to the parsing/binding process would be beneficial.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 53 4/2/2026
2.0.0 84 3/24/2026
1.0.1 80 3/22/2026
1.0.0 80 3/22/2026

3.0.0 - Improved support for complex command lines, where a single utility handles multiple
commands (a la the dotnet and azure CLIs), including a CommandDispatcher.

2.0.0 - Addition of "help switches". The presence of a defined help switch on a command line
weakens ordinary validation (parse errors surface as warnings instead), so that a command
line that doesn't really need to be valid anyway (help is being requested) can be parsed.