You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用System.CommandLine实现NodaTime.Duration的命令行参数绑定

问题解答

绑定支持说明

  • System.TimeSpan可以直接绑定:System.CommandLine内置了TimeSpan的类型转换逻辑,直接声明Option<TimeSpan>即可正常解析命令行输入,无需额外配置。
  • NodaTime.Duration默认不支持直接绑定,但可以通过自定义转换逻辑实现需求。

实现NodaTime.Duration绑定的两种方案

方案1:针对单个Option指定解析逻辑

直接在定义Option<Duration>时传入parseArgument委托实现自定义解析,适合仅少数地方使用Duration参数的场景,示例代码如下:

using NodaTime;
using System.CommandLine;
using System.CommandLine.NamingConventionBinder;

static void Main(string[] args)
{
    // 定义带自定义解析逻辑的Duration参数
    var durationOption = new Option<Duration>(
        name: "--my-duration",
        parseArgument: result =>
        {
            string input = result.Tokens.Single().Value;
            // 可根据业务需求调整解析规则,比如支持"1h""30m"等简写格式
            if (Duration.TryParse(input, out var validDuration))
            {
                return validDuration;
            }
            // 解析失败时返回错误提示
            result.ErrorMessage = $"输入值 {input} 无法转换为合法的Duration类型";
            return default;
        });

    var rootCommand = new RootCommand
    {
        durationOption
    };

    rootCommand.Handler = CommandHandler.Create(
        (Duration myDuration) => { Console.WriteLine(myDuration); });

    rootCommand.InvokeAsync(args).Wait();
}

方案2:注册全局类型转换器

如果项目中多处使用Duration作为命令行参数,可注册全局TypeConverter避免重复编写解析逻辑,步骤如下:

  1. 自定义Duration的TypeConverter
using System.ComponentModel;
using NodaTime;

public class DurationTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType)
    {
        return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
    }

    public override object? ConvertFrom(ITypeDescriptorContext? context, System.Globalization.CultureInfo? culture, object value)
    {
        if (value is string input && Duration.TryParse(input, out var duration))
        {
            return duration;
        }
        return base.ConvertFrom(context, culture, value);
    }
}
  1. 程序启动时注册转换器,之后即可直接按原生方式声明Option<Duration>
// 注册全局转换器
TypeDescriptor.AddAttributes(typeof(Duration), new TypeConverterAttribute(typeof(DurationTypeConverter)));

// 后续可直接按原始代码写法使用
var rootCommand = new RootCommand
{
    new Option<Duration>("--my-duration"),
};
rootCommand.Handler = CommandHandler.Create(
    (Duration myDuration) => { Console.WriteLine(myDuration); });
rootCommand.InvokeAsync(args);

内容的提问来源于stack exchange,提问作者jack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 15:36:02