private void AddOption(OptionAttributeBase optionAttr, PropertyInfo prop) { CommandOption option; switch (optionAttr) { case HelpOptionAttribute h: option = h.Configure(App); break; case OptionAttribute o: option = o.Configure(App, prop); break; case VersionOptionAttribute v: option = v.Configure(App); break; default: throw new ArgumentOutOfRangeException(); } foreach (var attr in prop.GetCustomAttributes().OfType <ValidationAttribute>()) { option.Validators.Add(new AttributeValidator(attr)); } if (option.OptionType == CommandOptionType.NoValue && prop.PropertyType != typeof(bool)) { throw new InvalidOperationException(Strings.NoValueTypesMustBeBoolean); } if (option.ShortName != null) { if (_shortOptions.TryGetValue(option.ShortName, out var otherProp)) { throw new InvalidOperationException( Strings.OptionNameIsAmbiguous(option.ShortName, prop, otherProp)); } _shortOptions.Add(option.ShortName, prop); } if (option.LongName != null) { if (_longOptions.TryGetValue(option.LongName, out var otherProp)) { throw new InvalidOperationException( Strings.OptionNameIsAmbiguous(option.LongName, prop, otherProp)); } _longOptions.Add(option.LongName, prop); } var setter = ReflectionHelper.GetPropertySetter(prop); switch (option.OptionType) { case CommandOptionType.MultipleValue: var collectionParser = CollectionParserProvider.Default.GetParser(prop.PropertyType); if (collectionParser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => setter.Invoke(o, collectionParser.Parse(option.LongName, option.Values))); break; case CommandOptionType.SingleValue: var parser = ValueParserProvider.Default.GetParser(prop.PropertyType); if (parser == null) { throw new InvalidOperationException(Strings.CannotDetermineParserType(prop)); } OnBind(o => { var value = option.Value(); if (value == null) { return; } setter.Invoke(o, parser.Parse(option.LongName, value)); }); break; case CommandOptionType.NoValue: OnBind(o => setter.Invoke(o, option.HasValue())); break; default: throw new ArgumentOutOfRangeException(); } }