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); }
public static bool cliMakeDefault(PlTerm typeSpec, PlTerm valueOut) { CheckMI(); MethodInfo rc = MakeDefaultViaReflectionInfo.MakeGenericMethod(GetType(typeSpec)); return UnifyTagged(rc.Invoke(null, ZERO_OBJECTS), valueOut); }