/// <summary> /// Convert arguments to parameter types where they mismatch /// </summary> /// <param name='ctor'> /// Ctor. /// </param> /// <param name='args'> /// Arguments. /// </param> public static void ConformArguments(ParameterInfo[] paramlist, object[] args) { int i = -1; foreach (var parm in paramlist) { i++; object arg = args[i]; Type pclass = parm.ParameterType; Type aclass = arg != null?arg.GetType() : null; var ptype = ValueTypeUtils.TypeOf(pclass); var atype = ValueTypeUtils.TypeOf(aclass); if ((atype == ptype && atype != VType.Other) || pclass == aclass || pclass.IsAssignableFrom(aclass)) { continue; } if (arg == null && pclass.IsValueType) { throw new ArgumentException("could not find matching constructor"); } if (arg == null) { continue; } // convert simple value types to conform if (ptype != VType.Other) { args[i] = ValueTypeUtils.Convert(arg, ptype, pclass); } // special handling for delegates else if (DelegateGenerator.IsDelegate(pclass)) { args[i] = DelegateGenerator.ConvertToDelegate(pclass, args[i]); } // special case for ZDateTime, allowing long specifier else if (pclass == typeof(ZDateTime)) { if (aclass == typeof(long)) { args[i] = new ZDateTime((long)arg, ZTimeZone.NewYork); } else if (aclass == typeof(string)) { args[i] = new ZDateTime((string)arg); } else { throw new ArgumentException("unknown argument pairing"); } } // see if we can instantiate a persitable class else if (atype == VType.String && pclass.IsSubclassOf(typeof(IPersist <string>))) { var nobj = (IPersist <string>)Activator.CreateInstance(pclass); nobj.State = (string)arg; args[i] = nobj; } // the parameter type is an array, but our value is a single value of the same type, convert else if (pclass.IsArray && pclass.GetElementType() == aclass) { var narray = Array.CreateInstance(pclass.GetElementType(), 1); narray.SetValue(arg, 0); args[i] = narray; } else if (pclass == typeof(double [])) { if (typeof(Vector <double>).IsAssignableFrom(aclass)) { var vec = (Vector <double>)args [i]; var data = MatrixUtils.DataOf(vec); args [i] = data; } else if (aclass != typeof(double [])) { throw new ArgumentException("unknown argument pairing: " + aclass + " -> double[]"); } } else if (typeof(Vector <double>).IsAssignableFrom(pclass)) { if (aclass == typeof(double)) { var vec = new DenseVector(1); vec[0] = ((Double)args[i]); args[i] = vec; } if (aclass == typeof(int)) { var vec = new DenseVector(1); vec[0] = (double)((Int32)args[i]); args[i] = vec; } } // otherwise try to create a new instance from string else if (atype == VType.String) { string sval = (string)arg; try { var method = pclass.GetMethod("Parse"); if (method != null) { args[i] = method.Invoke(null, new object[] { sval }); continue; } } catch { } try { args[i] = Activator.CreateInstance(pclass, sval); } catch { throw new ArgumentException("could not coerce type " + aclass + " to " + pclass); } } } }