public static Func <object, object[], object[]> GetParamsConverter(ClrTypeConverter ctx, ParameterInfo[] methodParameters) { if (methodParameters.Length > 0) { var lastParameter = methodParameters.Last(); //have a deal with 'param' if (lastParameter.GetCustomAttribute <ParamArrayAttribute>() != null) { return((thisObject, argumentValues) => { if (argumentValues.Length < methodParameters.Length) { return ctx.ConvertParametersToClr(methodParameters, thisObject, argumentValues); } var part1Types = methodParameters.Take(methodParameters.Length - 1).ToArray(); var clrArgumentsPart1 = ctx.ConvertParametersToClr(part1Types, thisObject, argumentValues); var part2Types = Enumerable .Repeat(typeof(object), argumentValues.Length - part1Types.Length) .ToArray(); var clrArgumentsPart2 = ctx.ConvertParametersToClr(part2Types, thisObject, argumentValues.Skip(part1Types.Length).ToArray()); var clrArguments = new object[methodParameters.Length]; Array.Copy(clrArgumentsPart1, clrArguments, clrArgumentsPart1.Length); clrArguments[clrArguments.Length - 1] = clrArgumentsPart2; return clrArguments; }); } var expands = methodParameters .Select(parameterInfo => parameterInfo.GetCustomAttribute <JsExpandArrayAttribute>() != null) .ToArray(); var hasExpands = expands.Any(x => x); if (hasExpands || methodParameters.Any(x => !x.ParameterType.IsValueType)) { return((thisObject, argumentValues) => ctx.ConvertParametersToClr(methodParameters, thisObject, argumentValues)); } //Simple case with value parameters. var converters = methodParameters.Select(x => ctx.GetConverter(x.ParameterType, x.GetDefaultValue())); return((thisObject, args) => converters.Select((c, i) => c(i < args.Length ? args[i]: null)) .ToArray()); } return((_, __) => new object[0]); }
public static object[] ConvertParametersToClr(this ClrTypeConverter ctx, ParameterInfo[] methodParameters, object thisObject, object[] argumentValues) { var clrArguments = new object[methodParameters.Length]; for (var idx = 0; idx < clrArguments.Length; idx++) { var par = methodParameters[idx]; if (idx < argumentValues.Length) { //todo: optimize var expand = par.GetCustomAttribute <JsExpandArrayAttribute>() != null; var jsArgument = argumentValues[idx]; if (!expand && (par.ParameterType.IsValueType)) { clrArguments[idx] = ctx.GetConverter(par.ParameterType, par.GetDefaultValue())(jsArgument); } else { clrArguments[idx] = ctx.ConvertToClr( jsArgument, par.ParameterType, thisObject, expand); } } else { if (par.GetCustomAttribute <ParamArrayAttribute>() != null) { clrArguments[idx] = Activator.CreateInstance(par.ParameterType, 0); } else if (par.HasDefaultValue) { clrArguments[idx] = par.DefaultValue; } } } return(clrArguments); }