/// <summary> /// Provides the actual implementation for deserializing a value of type <see cref="T" />. /// </summary> /// <param name="value">The uninitialized value to serialize into. This value will have been created earlier using <see cref="BaseFormatter{T}.GetUninitializedObject" />.</param> /// <param name="reader">The reader to deserialize with.</param> protected override void DeserializeImplementation(ref T value, IDataReader reader) { // We sadly *must* box so that complex value types get their values properly set by reflection. // At least we only box these once. object boxedValue = value; var members = FormatterUtilities.GetSerializableMembersMap(typeof(T), this.OverridePolicy ?? reader.Context.Config.SerializationPolicy); EntryType entryType; string name; while ((entryType = reader.PeekEntry(out name)) != EntryType.EndOfNode && entryType != EntryType.EndOfArray && entryType != EntryType.EndOfStream) { if (string.IsNullOrEmpty(name)) { reader.Context.Config.DebugContext.LogError("Entry of type \"" + entryType + "\" in node \"" + reader.CurrentNodeName + "\" is missing a name."); reader.SkipEntry(); continue; } MemberInfo member; if (members.TryGetValue(name, out member) == false) { reader.Context.Config.DebugContext.LogWarning("Lost serialization data for entry \"" + name + "\" of type \"" + entryType + "\"in node \"" + reader.CurrentNodeName + "\"."); reader.SkipEntry(); continue; } Type expectedType = FormatterUtilities.GetContainedType(member); try { var serializer = Serializer.Get(expectedType); object entryValue = serializer.ReadValueWeak(reader); FormatterUtilities.SetMemberValue(member, boxedValue, entryValue); } catch (Exception ex) { reader.Context.Config.DebugContext.LogException(ex); } } value = (T)boxedValue; // Unbox }