/// <summary> /// Provides the actual implementation for serializing a value of type <see cref="T" />. /// </summary> /// <param name="value">The value to serialize.</param> /// <param name="writer">The writer to serialize with.</param> protected override void SerializeImplementation(ref T value, IDataWriter writer) { var members = FormatterUtilities.GetSerializableMembers(typeof(T), this.OverridePolicy ?? writer.Context.Config.SerializationPolicy); for (int i = 0; i < members.Length; i++) { var member = members[i]; Type type; var memberValue = FormatterUtilities.GetMemberValue(member, value); type = FormatterUtilities.GetContainedType(member); var serializer = Serializer.Get(type); try { serializer.WriteValueWeak(member.Name, memberValue, writer); } catch (Exception ex) { writer.Context.Config.DebugContext.LogException(ex); } } }
private static void ReplaceAllReferencesInGraph(object graph, object oldReference, object newReference, HashSet <object> processedReferences = null) { if (processedReferences == null) { processedReferences = new HashSet <object>(ReferenceEqualityComparer <object> .Default); } processedReferences.Add(graph); if (graph.GetType().IsArray) { Array array = (Array)graph; for (int i = 0; i < array.Length; i++) { var value = array.GetValue(i); if (object.ReferenceEquals(value, null)) { continue; } if (object.ReferenceEquals(value, oldReference)) { array.SetValue(newReference, i); value = newReference; } if (!processedReferences.Contains(value)) { ReplaceAllReferencesInGraph(value, oldReference, newReference, processedReferences); } } } else { var members = FormatterUtilities.GetSerializableMembers(graph.GetType(), SerializationPolicies.Everything); for (int i = 0; i < members.Length; i++) { FieldInfo field = (FieldInfo)members[i]; if (field.FieldType.IsPrimitive || field.FieldType == typeof(SerializationData) || field.FieldType == typeof(string)) { continue; } object value = field.GetValue(graph); if (object.ReferenceEquals(value, null)) { continue; } Type valueType = value.GetType(); if (valueType.IsPrimitive || valueType == typeof(SerializationData) || valueType == typeof(string)) { continue; } if (object.ReferenceEquals(value, oldReference)) { field.SetValue(graph, newReference); value = newReference; } if (!processedReferences.Contains(value)) { ReplaceAllReferencesInGraph(value, oldReference, newReference, processedReferences); } } } }