static object Create(Type type, List <PositionalArgument> arguments, Dictionary <string, NamedArgument> namedArguments) { var constructor = GetConstructor(type); var declaredParameters = constructor.GetParameters(); var actualParameters = new List <object>(); foreach (var declaredParameter in declaredParameters) { var named = declaredParameter.GetCustomAttribute <ParamArrayAttribute>() == null; if (named) { var key = NamedArgument.Normalize(declaredParameter.Name); var namedArgument = namedArguments[key]; if (namedArgument.IsArray) { actualParameters.Add(CreateTypedArray(namedArgument.ItemType, namedArgument.Values)); } else if (namedArgument.Values.Count != 0) { actualParameters.Add(namedArgument.Values.Single()); } else { actualParameters.Add(Default(declaredParameter.ParameterType)); } } else { actualParameters.Add(arguments.Single().Value); } } return(constructor.Invoke(actualParameters.ToArray())); }
public Parser(Type type, string[] arguments) { DemandSingleConstructor(type); UnusedArguments = new List <string>(); var positionalArguments = ScanPositionalArguments(type); var namedArguments = ScanNamedArguments(type); var paramsPositionalArgumentValues = new List <object>(); var queue = new Queue <string>(arguments); while (queue.Any()) { var item = queue.Dequeue(); if (IsNamedArgumentKey(item)) { var name = NamedArgument.Normalize(item); if (!namedArguments.ContainsKey(name)) { UnusedArguments.Add(item); if (queue.Any() && !IsNamedArgumentKey(queue.Peek())) { UnusedArguments.Add(queue.Dequeue()); } continue; } var namedArgument = namedArguments[name]; object value; bool requireValue = namedArgument.ItemType != typeof(bool); if (requireValue) { if (!queue.Any() || IsNamedArgumentKey(queue.Peek())) { throw new CommandLineException($"{item} is missing its required value."); } value = queue.Dequeue(); } else { value = true; } if (namedArgument.Values.Count == 1 && !namedArgument.IsArray) { throw new CommandLineException($"{item} cannot be specified more than once."); } namedArgument.Values.Add(Convert(namedArgument.ItemType, item, value)); } else { if (positionalArguments.Any()) { paramsPositionalArgumentValues.Add(item); } else { UnusedArguments.Add(item); } } } foreach (var positionalArgument in positionalArguments) { //Bind all of paramsPositionalArgumentValues to this argument. var itemType = positionalArgument.Type.GetElementType(); paramsPositionalArgumentValues = paramsPositionalArgumentValues .Select(x => Convert(itemType, positionalArgument.Name, x)).ToList(); positionalArgument.Value = CreateTypedArray(itemType, paramsPositionalArgumentValues); } Model = Create(type, positionalArguments, namedArguments); }