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); }
static CommandLine() { var args = Environment.GetCommandLineArgs(); Arguments = new CommandLineArguments(args.Skip(1)); }
private static MethodBindResult BindMethod(Type type, string defaultMethodName, CommandLineArguments arguments) { if (type == null) { throw new ArgumentNullException("type"); } if (arguments == null) { throw new ArgumentNullException("arguments"); } var methodName = defaultMethodName; if (arguments.ContainsKey("0")) { arguments = new CommandLineArguments(arguments); methodName = TypeConvert.ToString(arguments["0"]); arguments.RemoveAt(0); } var candidate = default(MethodInfo); var allMethods = type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); Array.Sort(allMethods, (x, y) => y.GetParameters().Length.CompareTo(x.GetParameters().Length)); foreach (var method in allMethods) { if (string.Equals(method.Name, methodName, StringComparison.OrdinalIgnoreCase) == false || !method.IsStatic || method.ReturnType != typeof(int) || IsHidden(method)) { continue; } candidate = method; var parameters = method.GetParameters(); var methodArgs = new object[parameters.Length]; foreach (var parameter in parameters) { var value = default(object); if (TryBindParameter(parameter, arguments, out value) == false) { goto nextMethod; } methodArgs[parameter.Position] = value; } return(new MethodBindResult(method, methodArgs)); nextMethod: ; } return(new MethodBindResult(methodName, candidate)); }