private static ParameterBindResult BindParameter(ParameterInfo parameter, CommandLineArguments arguments) { var expectedType = parameter.ParameterType; var value = default(object); try { if (expectedType == typeof(CommandLineArguments)) { value = new CommandLineArguments(arguments); } else if (arguments.TryGetValue(parameter.Name, out value) || arguments.TryGetValue((parameter.Position).ToString(), out value)) { if (expectedType.IsArray) { var elemType = expectedType.GetElementType(); Debug.Assert(elemType != null, "elemType != null"); if (value is IList <string> ) { var valuesStr = (IList <string>)value; var values = Array.CreateInstance(elemType, valuesStr.Count); for (var i = 0; i < valuesStr.Count; i++) { value = valuesStr[i]; // used on failure in exception block values.SetValue(Convert(valuesStr[i], elemType, parameter), i); } value = values; } else if (value != null) { var values = Array.CreateInstance(elemType, 1); values.SetValue(Convert(value, elemType, parameter), 0); value = values; } else { var values = Array.CreateInstance(elemType, 0); value = values; } } else if (expectedType == typeof(bool) && value == null) { value = true; } else if (value == null) { value = parameter.IsOptional ? parameter.DefaultValue : expectedType.GetTypeInfo().IsValueType ? TypeActivator.CreateInstance(expectedType) : null; } else if (expectedType.GetTypeInfo().IsEnum&& value is IList <string> ) { var valuesStr = (IList <string>)value; var values = new object[valuesStr.Count]; for (var i = 0; i < valuesStr.Count; i++) { value = valuesStr[i]; // used on failure in exception block values[i] = Convert(value, expectedType, parameter); } if (IsSigned(Enum.GetUnderlyingType(expectedType))) { var combinedValue = 0L; foreach (var enumValue in values) { value = enumValue; // used on failure in exception block combinedValue |= (long)TypeConvert.Convert(value, typeof(long)); } value = Enum.ToObject(expectedType, combinedValue); } else { var combinedValue = 0UL; foreach (var enumValue in values) { value = enumValue; // used on failure in exception block combinedValue |= (ulong)TypeConvert.Convert(enumValue, typeof(ulong)); } value = Enum.ToObject(expectedType, combinedValue); } } else if (value is IList <string> && expectedType.GetTypeInfo().IsAssignableFrom(typeof(IList <string>).GetTypeInfo()) == false) { throw new FormatException(string.Format("Parameter has {0} values while only one is expected.", ((IList <string>)value).Count)); } else { value = Convert(value, expectedType, parameter); } } else if (parameter.IsOptional) { value = parameter.DefaultValue; } else if (expectedType == typeof(bool)) { value = false; } else { throw new InvalidOperationException("Missing parameter value."); } } catch (Exception bindingError) { return(new ParameterBindResult(parameter, bindingError, value)); } if (value != null && value.GetType() != parameter.ParameterType) { value = TypeConvert.Convert(value, parameter.ParameterType); } return(new ParameterBindResult(parameter, null, value)); }
private static bool TryBindParameter(ParameterInfo parameter, CommandLineArguments arguments, out object value) { var expectedType = parameter.ParameterType; if (expectedType == typeof(CommandLineArguments)) { value = new CommandLineArguments(arguments); } else if (arguments.TryGetValue(parameter.Name, out value) || arguments.TryGetValue((parameter.Position).ToString(), out value)) { if (expectedType.IsArray) { var elemType = expectedType.GetElementType(); Debug.Assert(elemType != null, "elemType != null"); if (value is string[]) { var oldArr = value as string[]; var newArr = Array.CreateInstance(elemType, oldArr.Length); for (var v = 0; v < oldArr.Length; v++) { newArr.SetValue(TypeConvert.Convert(typeof(string), elemType, oldArr[v]), v); } value = newArr; } else if (value != null) { var newArr = Array.CreateInstance(elemType, 1); newArr.SetValue(TypeConvert.Convert(value.GetType(), elemType, value), 0); value = newArr; } else { var newArr = Array.CreateInstance(elemType, 0); value = newArr; } } else if (expectedType == typeof(bool) && value == null) { value = true; } else if (value == null) { value = parameter.IsOptional ? parameter.DefaultValue : expectedType.IsValueType ? TypeActivator.CreateInstance(expectedType) : null; } else if (expectedType.IsEnum && value is string[]) { var valuesStr = (string[])value; var values = Array.ConvertAll(valuesStr, v => TypeConvert.Convert(typeof(string), expectedType, v)); if (IsSigned(Enum.GetUnderlyingType(expectedType))) { var combinedValue = 0L; foreach (var v in values) { combinedValue |= (long)TypeConvert.Convert(expectedType, typeof(long), v); } value = Enum.ToObject(expectedType, combinedValue); } else { var combinedValue = 0UL; foreach (var v in values) { combinedValue |= (ulong)TypeConvert.Convert(expectedType, typeof(ulong), v); } value = Enum.ToObject(expectedType, combinedValue); } } else { value = TypeConvert.Convert(value.GetType(), expectedType, value); } } else if (parameter.IsOptional) { value = parameter.DefaultValue; } else if (expectedType == typeof(bool)) { value = false; } else { return(false); } return(true); }