コード例 #1
0
ファイル: ReflectUtils.cs プロジェクト: orellabac/.Net-Bridge
        /// <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); }
                }
            }
        }