public CommandLineParser() { var properties = typeof(T).GetProperties(); foreach (var propertyInfo in properties) { var positionalAttribute = propertyInfo.GetCustomAttribute <PositionalParameterAttribute>(); if (positionalAttribute != null) { // NOTE: kind of cheating and we should have some kind of interface - I don't want to do 2 ReadInput. var item = new ArgumentItem(propertyInfo, positionalAttribute.ToParameterAttribute()); positionalArguments.Add(item); } else { var item = new ArgumentItem(propertyInfo, propertyInfo.GetCustomAttribute <ParameterAttribute>()); if (item.GetAlias() != 0) { aliases.Add(item.GetAlias(), item); } if (!string.IsNullOrEmpty(item.GetAction())) { actions.Add(item.GetAction(), item); } explicitArguments.Add(item); } } }
private void ReadInput(T newItem, ArgumentItem argumentItem, string[] args, ref int i, bool isPositional = false) { if (argumentItem.PropertyInfo.PropertyType == typeof(bool)) { argumentItem.PropertyInfo.SetValue(newItem, true); } else if (typeof(IList).IsAssignableFrom(argumentItem.PropertyInfo.PropertyType) && argumentItem.PropertyInfo.PropertyType.IsGenericType) { var listType = typeof(List <>); var listItemType = argumentItem.PropertyInfo.PropertyType.GenericTypeArguments[0]; var constructedListType = listType.MakeGenericType(listItemType); var list = (IList)Activator.CreateInstance(constructedListType); if (list == null) { throw new NullReferenceException($"The property of type list hasn't been initialized. See {newItem.GetType().Name}.{argumentItem.PropertyInfo.Name}'"); } var increment = isPositional ? 0 : 1; for (; i + increment < args.Length; i++) { var input = args[i + increment]; if (input.StartsWith('-')) { break; } list.Add(ConvertValue(input, listItemType, argumentItem.GetConverter())); } argumentItem.PropertyInfo.SetValue(newItem, list); } else if (argumentItem.PropertyInfo.PropertyType.IsArray) { var listItemType = argumentItem.PropertyInfo.PropertyType.GetElementType(); if (listItemType == null) { throw new Exception("Since we check the array type, this shouldn't happen.'"); } var listType = typeof(List <>).MakeGenericType(listItemType); var list = (IList)Activator.CreateInstance(listType); var increment = isPositional ? 0 : 1; for (; i + increment < args.Length; i++) { var input = args[i + increment]; if (input.StartsWith('-')) { break; } list.Add(ConvertValue(input, listItemType, argumentItem.GetConverter())); } var array = Array.CreateInstance(listItemType, list.Count); list.CopyTo(array, 0); argumentItem.PropertyInfo.SetValue(newItem, array); } else if (argumentItem.PropertyInfo.PropertyType.IsEnum) { if (Enum.TryParse(argumentItem.PropertyInfo.PropertyType, ReadParameter(args, ref i, argumentItem.GetAction(), isPositional), true, out var result)) { argumentItem.PropertyInfo.SetValue(newItem, result); } else { throw new CommandArgumentException($"Error parsing the enum for property {argumentItem.PropertyInfo.Name}."); } } else if (argumentItem.PropertyInfo.PropertyType == typeof(FileInfo)) { argumentItem.PropertyInfo.SetValue(newItem, new FileInfo(ReadParameter(args, ref i, argumentItem.GetAction(), isPositional))); } else if (argumentItem.PropertyInfo.PropertyType == typeof(DirectoryInfo)) { argumentItem.PropertyInfo.SetValue(newItem, new DirectoryInfo(ReadParameter(args, ref i, argumentItem.GetAction(), isPositional))); } else { argumentItem.PropertyInfo.SetValue(newItem, ConvertValue(ReadParameter(args, ref i, argumentItem.GetAction(), isPositional), argumentItem.PropertyInfo.PropertyType, argumentItem.GetConverter())); } }