CommandLineUtils 命令行参数解析:Arguments 详解

CommandLineUtils 命令行参数解析:Arguments 详解

引言

在开发命令行工具时,参数解析是最基础也是最重要的功能之一。CommandLineUtils 是一个强大的.NET命令行参数解析库,它提供了两种方式来定义和解析命令行参数:通过特性(Attributes)和构建器API(Builder API)。本文将深入讲解CommandLineUtils中Arguments(位置参数)的使用方法。

基本概念

命令行参数通常分为两类:

  1. Arguments(位置参数):通过位置顺序来识别,不需要参数名
  2. Options(选项参数):通过名称来识别,需要参数名(将在其他文章中详细介绍)

基础用法

使用特性(Attributes)方式

特性方式通过在类属性上添加[Argument]特性来定义位置参数:

public class Program
{
    // 定义第一个位置参数(索引0),并标记为必填
    [Argument(0)]
    [Required]
    public string FirstName { get; }

    // 定义第二个位置参数(索引1),可选
    [Argument(1)]
    public string LastName { get; }

    private void OnExecute()
    {
        Console.WriteLine($"Hello {FirstName} {LastName}");
    }

    public static int Main(string[] args) => CommandLineApplication.Execute<Program>(args);
}

使用示例:

myapp John Doe
  • John会被赋值给FirstName
  • Doe会被赋值给LastName

使用构建器API(Builder API)方式

构建器API提供了更灵活的编程方式来定义参数:

public class Program
{
    public static int Main(string[] args)
    {
        var app = new CommandLineApplication();

        // 定义第一个位置参数
        var firstNameArg = app.Argument("first name", "the first name of the person")
            .IsRequired();
        
        // 定义第二个位置参数
        var lastNameArg = app.Argument("last name", "the last name of the person");

        app.OnExecute(() =>
        {
            Console.WriteLine($"Hello {firstNameArg.Value} {lastNameArg.Value}");
        });

        return app.Execute(args);
    }
}

可变数量参数

有时我们需要处理数量不定的参数,比如处理多个文件:

myapp file1.txt file2.txt file3.txt

特性方式实现

public class Program
{
    [Argument(0)]
    public string[] Files { get; } // 自动收集所有位置参数

    private void OnExecute()
    {
        foreach (var file in Files)
        {
            // 处理每个文件
        }
    }

    public static int Main(string[] args) => CommandLineApplication.Execute<Program>(args);
}

构建器API实现

public class Program
{
    public static int Main(string[] args)
    {
        var app = new CommandLineApplication();
        
        // 设置multipleValues为true以接收多个值
        var files = app.Argument("Files", "Files to process", multipleValues: true);
        
        app.OnExecute(() =>
        {
            foreach (var file in files.Values)
            {
                // 处理每个文件
            }
        });
        
        return app.Execute(args);
    }
}

参数透传

开发包装其他命令的工具时,经常需要将部分参数透传给内部命令。例如Unix的time命令:

time -l ls -a -l ./

特性方式实现

public class Program
{
    [Option("-l")]
    public bool ShowDetails { get; }

    // 剩余参数会自动收集到RemainingArguments属性
    public string[] RemainingArguments { get; }

    private void OnExecute()
    {
        // 使用RemainingArguments中的参数调用其他命令
    }

    public static int Main(string[] args) => CommandLineApplication.Execute<Program>(args);
}

构建器API实现

public class Program
{
    public static int Main(string[] args)
    {
        var app = new CommandLineApplication
        {
            // 设置如何处理未识别参数
            UnrecognizedArgumentHandling = UnrecognizedArgumentHandling.StopParsingAndCollect,
            // 允许使用--分隔符
            AllowArgumentSeparator = true
        };

        var showDetails = app.Option("-l", "Show details", CommandOptionType.NoValue);
        
        app.OnExecute(() =>
        {
            // 使用app.RemainingArguments调用其他命令
        });
        
        return app.Execute(args);
    }
}

最佳实践

  1. 参数顺序:重要的、必填的参数应该放在前面
  2. 参数说明:始终为参数提供清晰的描述信息
  3. 默认值:为可选参数提供合理的默认值
  4. 参数验证:对参数值进行有效性检查
  5. 使用--分隔符:在透传参数时,推荐支持--分隔符以明确区分参数

总结

CommandLineUtils提供了灵活强大的参数解析能力,无论是简单的固定参数还是复杂的可变参数、透传参数场景,都能很好地支持。通过特性方式可以快速定义参数,而构建器API则提供了更细粒度的控制。开发者可以根据项目需求选择合适的方式来实现命令行参数解析功能。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奚子萍Marcia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值