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

如何为System.CommandLine同一选项传递多个值?

如何在C#控制台应用中通过命令行传递多个数字参数?

初始问题

我想给C#控制台应用传递多个数字,代码示例如下:

private const long DEFAULT_ALPHA_VALUE = 1234567890L;
private static long[] alphas = { DEFAULT_ALPHA_VALUE };

public static async Task Main()
{
    Option<long[]> alphaOption = new
    (
        aliases: new[] { "-a", "--alpha" },
        getDefaultValue: () => new[] { DEFAULT_ALPHA_VALUE },
        description: "Numerical alpha values"
    );

    RootCommand rootCommand = new("A test app for multiple numerical values option");
    rootCommand.AddGlobalOption(alphaOption);
    rootCommand.SetHandler(a => { alphas = a; }, alphaOption);
    
    await RunInvokeAsync(rootCommand, "-a", "1234");
    await RunInvokeAsync(rootCommand, "-a", "1234", "5678"); // 错误:Unrecognized command or argument '5678'.
    await RunInvokeAsync(rootCommand, "-a", "1234 5678"); // 错误:Cannot parse argument '1234 5678' for option '-a' as expected type 'System.Int64'.
    await RunInvokeAsync(rootCommand, "-a", "1234,5678"); // 错误:Cannot parse argument '1234,5678' for option '-a' as expected type 'System.Int64'.
}

private static async Task RunInvokeAsync(RootCommand rootCommand, params string[] args)
{
    int status = await rootCommand.InvokeAsync(args);
    Console.WriteLine($"args: {JsonSerializer.Serialize(args)}, status: {status}, alphas: {JsonSerializer.Serialize(alphas)}");
}

我期望用以下任意一种命令传递多个数字:

dotnet run --project MultipleValuesOption.csproj -- -a 1234 5678
dotnet run --project MultipleValuesOption.csproj -- -a 1234,5678

但运行时均出现错误,请问该如何正确传递多个数字?是代码逻辑有问题,还是调用方式不对?


更新后的问题

按照建议给选项添加了AllowMultipleArgumentsPerToken = true,但新增第二个选项后,参数仍未被正确读取。代码示例:

private const long DEFAULT_ALPHA_VALUE = 13579L;
private static long[] alphas = { DEFAULT_ALPHA_VALUE };
private const long DEFAULT_BETA_VALUE = 24680L;
private static long[] betas = { DEFAULT_BETA_VALUE };

public static async Task Main(string[] args)
{
    Option<long[]> alphaOption = new
    (
        aliases: new[] { "-a", "--alpha" },
        getDefaultValue: () => new[] { DEFAULT_ALPHA_VALUE },
        description: "Numerical alpha values"
    )
    { 
        AllowMultipleArgumentsPerToken = true,
    };

    Option<long[]> betaOption = new
    (
        aliases: new[] { "-b", "--beta" },
        getDefaultValue: () => new[] { DEFAULT_BETA_VALUE },
        description: "Numerical beta values"
    )
    {
        AllowMultipleArgumentsPerToken = true,
    };

    RootCommand rootCommand = new("A test app for multiple numerical values option");
    rootCommand.AddGlobalOption(alphaOption);
    rootCommand.AddGlobalOption(betaOption);
    rootCommand.SetHandler(a => { alphas = a; }, alphaOption);
    rootCommand.SetHandler(b => { betas = b; }, betaOption);

    await RunInvokeAsync(rootCommand, args);
    await RunInvokeAsync(rootCommand, "-a", "1234", "5678");
}

private static async Task RunInvokeAsync(RootCommand rootCommand, params string[] args)
{
    int status = await rootCommand.InvokeAsync(args);
    Console.WriteLine($"args: {JsonSerializer.Serialize(args)}, status: {status}, alphas: {JsonSerializer.Serialize(alphas)}, betas: {JsonSerializer.Serialize(betas)}");
}

输出显示alphas始终保持默认值13579,没有读取命令行传入的参数:

args: [], status: 0, alphas: [13579], betas: [24680]
args: ["-a","1234","5678"], status: 0, alphas: [13579], betas: [24680]

解决方案

1. 单选项多参数的正确配置

要支持-a 1234 5678这种空格分隔的多参数传递,需要为Option<long[]>配置两个关键属性:

  • AllowMultipleArgumentsPerToken = true:允许一个选项令牌后跟随多个参数值
  • Arity = ArgumentArity.ZeroOrMore:明确参数可以是0个或多个(数组类型默认已隐含,但显式设置更清晰)

修改后的单个选项代码:

Option<long[]> alphaOption = new(
    aliases: new[] { "-a", "--alpha" },
    getDefaultValue: () => new[] { DEFAULT_ALPHA_VALUE },
    description: "Numerical alpha values"
)
{
    AllowMultipleArgumentsPerToken = true,
    Arity = ArgumentArity.ZeroOrMore
};

此时使用dotnet run -- -a 1234 5678即可正确传递多个数字。

2. 多选项时的处理器绑定问题

你遇到的第二个问题是因为多次调用SetHandler会覆盖之前的处理器,RootCommand只能有一个主处理器。正确做法是创建一个包含所有选项参数的处理器,一次性绑定所有选项:

// 替换原来的两次SetHandler调用
rootCommand.SetHandler((a, b) => 
{
    alphas = a;
    betas = b;
}, alphaOption, betaOption);

这样就能同时读取-a和-b的参数值。

3. 支持逗号分隔的参数(可选)

如果想同时支持-a 1234,5678这种逗号分隔的格式,需要自定义参数解析器:

Option<long[]> alphaOption = new(
    aliases: new[] { "-a", "--alpha" },
    parseArgument: (context, value) => 
    {
        // 分割逗号并转换为long数组
        return value.Split(',', StringSplitOptions.RemoveEmptyEntries)
                    .Select(long.Parse)
                    .ToArray();
    },
    getDefaultValue: () => new[] { DEFAULT_ALPHA_VALUE },
    description: "Numerical alpha values"
)
{
    AllowMultipleArgumentsPerToken = true,
    Arity = ArgumentArity.ZeroOrMore
};

此时两种传递方式-a 1234 5678和-a 1234,5678都能生效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:26:06