public void GenericCallUtilityTestsSimplePasses() { var s = new Sample(); { var mi = s.GetType().GetMethod("Set"); var action = GenericInvokeCallFactory.OpenAction <Sample, int>(mi); action(s, 1); Assert.AreEqual(1, s.Value); } { var mi = s.GetType().GetMethod("Get"); var func = GenericInvokeCallFactory.OpenFunc <Sample, int, int>(mi); /*var value =*/ func(s, 1); Assert.AreEqual(1, s.Value); } { var mi = s.GetType().GetMethod("Set"); var action = GenericExpressionCallFactory.Create <Sample, int>(mi); action(s, 2); Assert.AreEqual(2, s.Value); } }
static Func <ListTreeNode <T>, U> GetDeserializer() { // primitive { var mi = typeof(T).GetMethods() .Where(x => x.Name.StartsWith("Get")) .FirstOrDefault(IsPrimitiveDeserializer) ; if (mi != null) { var getter = GenericInvokeCallFactory.OpenFunc <T, U>(mi); return(s => getter(s.Value)); } } var target = typeof(U); if (target.IsArray) { var mi = typeof(GenericDeserializer <T, U>).GetMethod("GenericArrayDeserializer", BindingFlags.Static | BindingFlags.Public); var g = mi.MakeGenericMethod(target.GetElementType()); return(GenericInvokeCallFactory.StaticFunc <ListTreeNode <T>, U>(g)); } if (target.IsGenericType) { if (target.GetGenericTypeDefinition() == typeof(List <>)) { var mi = typeof(GenericDeserializer <T, U>).GetMethod("GenericListDeserializer", BindingFlags.Static | BindingFlags.Public); var g = mi.MakeGenericMethod(target.GetGenericArguments()); return(GenericInvokeCallFactory.StaticFunc <ListTreeNode <T>, U>(g)); } if (target == typeof(Dictionary <string, object>)) { var mi = typeof(GenericDeserializer <T, U>).GetMethod("DefaultDictionaryDeserializer", BindingFlags.Static | BindingFlags.Public); return(GenericInvokeCallFactory.StaticFunc <ListTreeNode <T>, U>(mi)); } else if (target.GetGenericTypeDefinition() == typeof(Dictionary <,>) && target.GetGenericArguments()[0] == typeof(string)) { var mi = typeof(GenericDeserializer <T, U>).GetMethod("DictionaryDeserializer", BindingFlags.Static | BindingFlags.Public); var g = mi.MakeGenericMethod(target.GetGenericArguments()[1]); return(GenericInvokeCallFactory.StaticFunc <ListTreeNode <T>, U>(g)); } if (target.GetGenericTypeDefinition() == typeof(Nullable <>)) { var mi = typeof(GenericDeserializer <T, U>).GetMethod("GenericNullableDeserializer", BindingFlags.Static | BindingFlags.Public); var g = mi.MakeGenericMethod(target.GetGenericArguments()); return(GenericInvokeCallFactory.StaticFunc <ListTreeNode <T>, U>(g)); } } if (target.IsEnum) { var value = Expression.Parameter(typeof(int), "value"); var cast = Expression.Convert(value, target); var func = Expression.Lambda(cast, value); var compiled = (Func <int, U>)func.Compile(); return(s => { if (s.IsString()) { return (U)Enum.Parse(typeof(U), s.GetString(), true); } else { return compiled(s.GetInt32()); } }); } // reflection { var fields = target.GetFields(BindingFlags.Instance | BindingFlags.Public); var fieldDeserializers = fields.ToDictionary(x => Utf8String.From(x.Name), x => { var mi = typeof(GenericDeserializer <T, U>).GetMethod("GetFieldDeserializer", BindingFlags.Static | BindingFlags.NonPublic); var g = mi.MakeGenericMethod(x.FieldType); return((FieldSetter)g.Invoke(null, new object[] { x })); }); return(s => { if (!s.IsMap()) { throw new ArgumentException(s.Value.ValueType.ToString()); } var t = (object)default(GenericConstructor <T, U>).Create(s); foreach (var kv in s.ObjectItems()) { FieldSetter setter; if (fieldDeserializers.TryGetValue(kv.Key.GetUtf8String(), out setter)) { setter(kv.Value, t); } } return (U)t; }); } }