Beispiel #1
0
        private static Func <object, object> findConversions(Type from, Type to, ICollection <Func <object, object> > allMethods)
        {
            Func <object, object> meth;

            if (to.IsAssignableFrom(from))
            {
                meth = (r) => r;
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            Func <object, object> sysmeth = (r) =>
            {
                CheckMI();
                if (r == null)
                {
                    MethodInfo rc = MakeDefaultViaReflectionInfo.MakeGenericMethod(to);
                    return(rc.Invoke(null, ZERO_OBJECTS));
                }
                else
                {
                    MethodInfo rc = MissingMI.MakeGenericMethod(to);
                    return(rc.Invoke(null, new[] { r }));
                }
            };

            if (to.IsValueType)
            {
                if (allMethods != null)
                {
                    allMethods.Add(sysmeth);
                }
                else
                {
                    // dont return .. this is the fallthru at bottem anyhow
                    // return sysmeth;
                }
            }
            if (to.IsEnum)
            {
                meth = (r) =>
                {
                    if (r == null)
                    {
                        return(null);
                    }
                    return(Enum.Parse(to, r.ToString()));
                };
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            if (to.IsPrimitive)
            {
                meth = ((r) => Convert.ChangeType(r, to));
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            if (to.IsArray && from.IsArray)
            {
                var eto   = to.GetElementType();
                var efrom = from.GetElementType();
                meth = ((r) =>
                {
                    Array ar = ((Array)r);
                    int len = ar.Length;
                    Array ret = Array.CreateInstance(eto, len);
                    for (int i = 0; i < len; i++)
                    {
                        ret.SetValue(RecastObject(eto, ar.GetValue(i), efrom), i);
                    }
                    return(ret);
                });
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            ConstructorInfo ci = to.GetConstructor(new Type[] { from });

            if (ci != null)
            {
                meth = (r) => ci.Invoke(new object[] { r });
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            ConstructorInfo pc = null;

            foreach (ConstructorInfo mi in to.GetConstructors(BindingFlagsALL))
            {
                var ps = mi.GetParameters();
                if (ps.Length == 0 && !mi.IsStatic)
                {
                    pc = mi;
                    continue;
                }
                if (ps.Length == 1)
                {
                    Type pt = ps[0].ParameterType;
                    if (pt.IsAssignableFrom(from))
                    {
                        ConstructorInfo info = mi;
                        meth = (r) => info.Invoke(new object[] { r });
                        if (allMethods != null)
                        {
                            allMethods.Add(meth);
                        }
                        else
                        {
                            return(meth);
                        }
                    }
                }
            }
            // search for op_Implicit/Explicit
            var someStatic = SomeConversionStaticMethod(to, to, from, allMethods, false);

            if (someStatic != null)
            {
                return(someStatic);
            }
            // search for op_Implicit/Explicit
            someStatic = SomeConversionStaticMethod(to, from, from, allMethods, false);
            if (someStatic != null)
            {
                return(someStatic);
            }

            if (ConvertorClasses.Count == 0)
            {
                ConvertorClasses.Add(typeof(Convert));
                ConvertorClasses.Add(typeof(PrologConvert));
                //ConvertorClasses.Add(typeof(PrologCLR));
            }
            foreach (Type convertorClasse in ConvertorClasses)
            {
                var someStaticM = SomeConversionStaticMethod(to, convertorClasse, from, allMethods, false);
                if (someStaticM != null)
                {
                    return(someStatic);
                }
            }
            //if (PrologBinder.CanConvertFrom(from, to))
            {
                meth = (r) => Convert.ChangeType(r, to);
                if (allMethods != null)
                {
                    allMethods.Add(meth);
                }
                else
                {
                    return(meth);
                }
            }
            // search for toWhatnot (very bad should be done last)
            foreach (MethodInfo mi in from.GetMethods(BindingFlagsInstance))
            {
                if (!mi.IsStatic)
                {
                    var ps = mi.GetParameters();
                    if (ps.Length == 0)
                    {
                        if (!to.IsAssignableFrom(mi.ReturnType))
                        {
                            continue;
                        }
                        //Type pt = ps[0].ParameterType;
                        //if (pt.IsAssignableFrom(from))
                        {
                            MethodInfo info = mi;
                            meth = (r) => info.Invoke(r, ZERO_OBJECTS);
                            if (allMethods != null)
                            {
                                allMethods.Add(meth);
                            }
                            else
                            {
                                return(meth);
                            }
                        }
                    }
                }
            }
            // search for to.Whatnot (very very bad should be done last)
            if (pc != null)
            {
                meth = null;
                int fieldCount = 0;
                foreach (var f in to.GetFields(BindingFlagsInstance))
                {
                    fieldCount++;
                    if (fieldCount > 1)
                    {
                        // too many fields
                        break;
                    }
                    FieldInfo info = f;
                    meth = (r) =>
                    {
                        var ret = pc.Invoke(null);
                        info.SetValue(ret, r);
                        return(ret);
                    };
                }
                if (fieldCount == 1 && meth != null)
                {
                    if (allMethods != null)
                    {
                        allMethods.Add(meth);
                    }
                    else
                    {
                        return(meth);
                    }
                }
            }

            return(sysmeth);
        }
Beispiel #2
0
 public static bool cliMakeDefault(PlTerm typeSpec, PlTerm valueOut)
 {
     CheckMI();
     MethodInfo rc = MakeDefaultViaReflectionInfo.MakeGenericMethod(GetType(typeSpec));
     return UnifyTagged(rc.Invoke(null, ZERO_OBJECTS), valueOut);
 }