public object Deserialize(BinaryReader reader, SerializationManager manager) { var res = new TConcrete(); while (true) { var name = reader.ReadString(); if (string.IsNullOrEmpty(name)) { break; } var value = manager.Deserialize(reader); if (TargetProperties.TryGetValue(name, out var pi)) { pi.SetValue(res, value); } else if (value is IEnumerable enumerable && TargetCollectionProperties.TryGetValue(name, out pi)) { var collection = pi.GetValue(res); if (collection == null) { continue; } foreach (var i in value.GetType().GetInterfaces()) { if (i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { var add = collection.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy).Where(m => m.Name == "Add" && m.GetParameters() is ParameterInfo[] parameters && parameters.Length == 1 && parameters[0].ParameterType == i.GenericTypeArguments[0]).FirstOrDefault(); if (add == null) { continue; } var enumeratorMethod = i.GetMethod("GetEnumerator"); var enumerator = (IEnumerator)enumeratorMethod.Invoke(value, null); while (enumerator.MoveNext()) { add.Invoke(collection, new object[] { enumerator.Current }); } break; } } } } return(res); }
public override bool TryGetMember(GetMemberBinder binder, out object result) { PropertyInfo property; if (TargetProperties.TryGetValue(binder.Name, out property)) { result = property.GetValue(Target); return(true); } else { result = null; return(false); } }