コード例 #1
0
ファイル: ReflectUtils.cs プロジェクト: jar1karp/.Net-Bridge
        /// <summary>
        /// Determine penalty for mismatched arguments (- is penalty and + is a reward)
        /// </summary>
        /// <returns>
        /// The penalty.
        /// </returns>
        /// <param name='paramclass'>
        /// parameter class.
        /// </param>
        /// <param name='argclass'>
        /// class of given argument.
        /// </param>
        internal static int ArgumentPenalty(Type paramclass, Type argclass)
        {
            if (typeof(Vector <double>).IsAssignableFrom(paramclass))
            {
                if (typeof(Vector <double>).IsAssignableFrom(argclass))
                {
                    return(100);
                }
                if (argclass == typeof(double) || argclass == typeof(int))
                {
                    return(50);
                }
                else
                {
                    return(-100);
                }
            }

            if (paramclass == typeof(string) && argclass == null)
            {
                return(100);
            }
            if (!paramclass.IsValueType && argclass == null)
            {
                return(100);
            }
            if (paramclass.IsArray && paramclass.GetElementType() == argclass)
            {
                return(10);
            }
            if (!paramclass.IsValueType)
            {
                return(-100);
            }

            var paramtype = ValueTypeUtils.TypeOf(paramclass);
            var argtype   = ValueTypeUtils.TypeOf(argclass);

            if (paramtype == argtype && paramtype != VType.Other)
            {
                return(100);
            }

            switch (paramtype)
            {
            case VType.Short:
                switch (argtype)
                {
                case VType.Int:
                case VType.Long:
                    return(50);

                case VType.Float:
                case VType.Double:
                    return(20);

                default:
                    return(-50);
                }

            case VType.Int:
                switch (argtype)
                {
                case VType.Long:
                    return(50);

                case VType.Short:
                case VType.Float:
                case VType.Double:
                    return(75);

                default:
                    return(-50);
                }

            case VType.Long:
                switch (argtype)
                {
                case VType.Short:
                case VType.Int:
                case VType.Float:
                case VType.Double:
                    return(50);

                default:
                    return(-50);
                }

            case VType.Float:
                switch (argtype)
                {
                case VType.Float:
                case VType.Double:
                    return(100);

                case VType.Long:
                    return(20);

                case VType.Short:
                case VType.Int:
                    return(50);

                default:
                    return(-50);
                }

            case VType.Double:
                switch (argtype)
                {
                case VType.Int:
                case VType.Short:
                case VType.Long:
                    return(50);

                case VType.Float:
                case VType.Double:
                    return(100);

                default:
                    return(-50);
                }

            case VType.Bool:
                switch (argtype)
                {
                case VType.Long:
                case VType.Float:
                case VType.Double:
                    return(20);

                case VType.Int:
                case VType.Short:
                case VType.Byte:
                case VType.Char:
                    return(50);

                default:
                    return(-50);

                case VType.Enum:
                    switch (argtype)
                    {
                    case VType.Int:
                        return(50);

                    case VType.String:
                        return(100);

                    default:
                        return(-50);
                    }
                }
            }

            if (paramclass == typeof(ZDateTime))
            {
                if (argclass == typeof(string))
                {
                    return(20);
                }
                if (argclass == typeof(long))
                {
                    return(50);
                }
                else
                {
                    return(-50);
                }
            }

            return(-100);
        }
コード例 #2
0
ファイル: ReflectUtils.cs プロジェクト: jar1karp/.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 (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); }
                }
            }
        }