如何在CommandLineParser中根据其他选项值设置选项为必填?
实现依赖条件的必填选项(CommandLineParser库)
你直接在Option特性的Required参数中写Foo == "egg"是无效的——类初始化阶段Foo还未被赋值,这个表达式只会被计算一次(结果为false),无法动态根据解析后的Foo值判断Bar是否必填。
正确的做法是在解析完成后添加自定义验证逻辑,以下是两种可行实现方式:
方式一:解析后直接验证
先正常定义选项类,将Bar设为非必填:
using CommandLine; public class Options { [Option('f', "foo", Required = true, HelpText = "Name of process")] public string Foo { get; set; } [Option('b', "bar", HelpText = "Required when 'foo' is set to 'egg'")] public string Bar { get; set; } }
然后在解析完成后添加条件验证:
class Program { static void Main(string[] args) { Parser.Default.ParseArguments<Options>(args) .WithParsed(options => { // 当Foo等于"egg"时,检查Bar是否为空 if (options.Foo == "egg" && string.IsNullOrEmpty(options.Bar)) { throw new CommandLineArgumentException( "Option '--bar' is required when '--foo' is 'egg'", nameof(Options.Bar)); } // 验证通过后执行业务逻辑 RunLogic(options); }) .WithNotParsed(errors => { // 处理解析错误 HandleErrors(errors); }); } private static void RunLogic(Options options) { // 你的业务代码 } private static void HandleErrors(IEnumerable<Error> errors) { // 错误处理逻辑 } }
方式二:用IValidatableObject封装验证逻辑
让选项类实现IValidatableObject,把验证逻辑封装在类内部:
using CommandLine; using System.ComponentModel.DataAnnotations; public class Options : IValidatableObject { [Option('f', "foo", Required = true, HelpText = "Name of process")] public string Foo { get; set; } [Option('b', "bar", HelpText = "Required when 'foo' is set to 'egg'")] public string Bar { get; set; } public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { if (Foo == "egg" && string.IsNullOrEmpty(Bar)) { yield return new ValidationResult( "Bar is required when Foo equals 'egg'", new[] { nameof(Bar) }); } } }
解析时启用数据验证:
Parser.Default.ParseArguments<Options>(args) .WithParsed(options => { var validationCtx = new ValidationContext(options); Validator.ValidateObject(options, validationCtx, validateAllProperties: true); RunLogic(options); }) .WithNotParsed(HandleErrors);
两种方式都能实现你要的逻辑:当Foo的值为"egg"时,强制要求必须提供Bar选项。
内容的提问来源于stack exchange,提问作者user5405648
相关产品推荐
相关产品推荐

