/// <summary> /// Writes a value of type <see cref="T" />. /// </summary> /// <param name="name">The name of the value to write.</param> /// <param name="value">The value to write.</param> /// <param name="writer">The writer to use.</param> public override void WriteValue(string name, T value, IDataWriter writer) { var context = writer.Context; var policy = context.Config.SerializationPolicy; if (policy.AllowNonSerializableTypes == false && TypeOf_T.IsSerializable == false) { context.Config.DebugContext.LogError("The type " + TypeOf_T.Name + " is not marked as serializable."); return; } FireOnSerializedType(); if (ComplexTypeIsValueType) { bool endNode = true; try { writer.BeginStructNode(name, TypeOf_T); GetBaseFormatter(policy).Serialize(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } else { int id; int index; string strId; Guid guid; bool endNode = true; if (object.ReferenceEquals(value, null)) { writer.WriteNull(name); } else if (context.TryRegisterExternalReference(value, out index)) { writer.WriteExternalReference(name, index); } else if (context.TryRegisterExternalReference(value, out guid)) { writer.WriteExternalReference(name, guid); } else if (context.TryRegisterExternalReference(value, out strId)) { writer.WriteExternalReference(name, strId); } else if (context.TryRegisterInternalReference(value, out id)) { Type type = value.GetType(); // Get type of actual stored object if (ComplexTypeMayBeBoxedValueType && FormatterUtilities.IsPrimitiveType(type)) // It's a boxed primitive type { try { writer.BeginReferenceNode(name, type, id); var serializer = Serializer.Get(type); serializer.WriteValueWeak(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } else { IFormatter formatter; if (object.ReferenceEquals(type, TypeOf_T)) { formatter = GetBaseFormatter(policy); } else { formatter = FormatterLocator.GetFormatter(type, policy); } try { writer.BeginReferenceNode(name, type, id); formatter.Serialize(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } } else { writer.WriteInternalReference(name, id); } } }
/// <summary> /// Writes a value of type <see cref="T" />. /// </summary> /// <param name="name">The name of the value to write.</param> /// <param name="value">The value to write.</param> /// <param name="writer">The writer to use.</param> public override void WriteValue(string name, T value, IDataWriter writer) { var context = writer.Context; if (context.Config.SerializationPolicy.AllowNonSerializableTypes == false && typeof(T).IsSerializable == false) { context.Config.DebugContext.LogError("The type " + typeof(T).Name + " is not marked as serializable."); return; } FireOnSerializedType(); if (ComplexTypeIsValueType) { bool endNode = true; try { writer.BeginStructNode(name, typeof(T)); FormatterLocator.GetFormatter <T>(context.Config.SerializationPolicy).Serialize(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } else { int id; int index; string strId; Guid guid; bool endNode = true; if (object.ReferenceEquals(value, null)) { writer.WriteNull(name); } else if (context.TryRegisterExternalReference(value, out index)) { writer.WriteExternalReference(name, index); } else if (context.TryRegisterExternalReference(value, out guid)) { writer.WriteExternalReference(name, guid); } else if (context.TryRegisterExternalReference(value, out strId)) { writer.WriteExternalReference(name, strId); } else if (context.TryRegisterInternalReference(value, out id)) { // Get type of actual stored object // // Don't have it as a strongly typed T value, since people can "override" (shadow) // GetType() on derived classes with the "new" operator. By referencing the type // as a System.Object, we ensure the correct GetType() method is always called. // // (Yes, this has actually happened, and this was done to fix it.) Type type = (value as object).GetType(); if (ComplexTypeMayBeBoxedValueType && FormatterUtilities.IsPrimitiveType(type)) // It's a boxed primitive type { try { writer.BeginReferenceNode(name, type, id); var serializer = Serializer.Get(type); serializer.WriteValueWeak(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } else { var formatter = FormatterLocator.GetFormatter(type, context.Config.SerializationPolicy); try { writer.BeginReferenceNode(name, type, id); formatter.Serialize(value, writer); } catch (SerializationAbortException ex) { endNode = false; throw ex; } finally { if (endNode) { writer.EndNode(name); } } } } else { writer.WriteInternalReference(name, id); } } }