应优先使用现成命令行解析库而非手动遍历args:System.CommandLine(.NET 5+官方推荐)支持强类型绑定、自动help、子命令等;旧项目可用CommandLineParser。

直接用 args 数组就能拿到原始参数,但手动解析容易出错、不支持短选项、缺少类型转换和帮助生成——别自己写解析逻辑,优先用现成库。
为什么不用直接遍历 args?
虽然 static void Main(string[] args) 中的 args 确实包含所有参数,但手动处理会立刻遇到这些问题:
-
--port=8080和--port 8080要分别判断,还得处理空格、引号包裹的值(如"C:\My App") - 没有自动类型转换:你得自己调用
int.TryParse或DateTime.TryParse,还可能漏掉异常分支 - 无法生成标准 help 文本,
myapp.exe -h得手写输出逻辑 - 不支持子命令(如
git commit -m "msg")、重复选项(-v -v -v)、布尔开关(--verbose)等常见模式
推荐用 System.CommandLine(.NET 5+ 官方推荐)
这是微软维护的现代命令行解析库,已内置于 .NET 6+ SDK,.NET 5 需要安装 NuGet 包 System.CommandLine。它支持强类型绑定、自动 help、子命令、验证钩子。
基础用法示例(无子命令):
using System;
using System.CommandLine;
using System.CommandLine.Invocation;
var rootCommand = new RootCommand("My CLI tool")
{
new Option(new string[] { "--port", "-p" }, "Port number"),
new Option("--verbose", "Enable verbose output"),
new Argument("input", "Input file path")
};
rootCommand.Handler = CommandHandler.Create((port, verbose, input) =>
{
Console.WriteLine($"Port: {port}, Verbose: {verbose}, Input: {input}");
});
await rootCommand.InvokeAsync(args);
运行效果:
-
myapp.exe --port 3000 --verbose data.txt→ 正确绑定 -
myapp.exe -h→ 自动输出格式化 help -
myapp.exe --port abc data.txt→ 自动报错并提示类型错误
兼容旧项目?用 CommandLineParser(.NET Framework / .NET Core 3.1)
如果还在用 .NET Framework 或不能升级到 .NET 5+,CommandLineParser(NuGet 包名 CommandLineParser)仍是稳定选择,语法更接近属性标记风格。
Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统
定义选项类:
class Options
{
[Option('p', "port", Required = true, HelpText = "Server port")]
public int Port { get; set; }
[Option("verbose", Default = false, HelpText = "Enable verbose logging")]
public bool Verbose { get; set; }
[Value(0, MetaName = "INPUT", HelpText = "Input file path")]
public string InputFile { get; set; }
}
解析调用:
var result = Parser.Default.ParseArguments(args); result.WithParsed (o => { Console.WriteLine($"Port: {o.Port}, Verbose: {o.Verbose}, File: {o.InputFile}"); });
注意:它不支持异步主入口,且对长参数名拼写容错较弱(比如 --por 不会提示近似建议)。
真正麻烦的不是“怎么取参数”,而是“怎么让参数行为符合用户预期”——比如 --help 是否响应所有层级、错误时是否静默退出、缺失必填项是否中断执行。这些细节在 System.CommandLine 里是开箱即用的,在手写逻辑里往往到上线前一周才被发现。








