Search code examples
c#serializationdatacontractobject-graph

Clone Whole Object Graph


While using this code to serialize an object:

public object Clone()
{
    var serializer = new DataContractSerializer(GetType());
    using (var ms = new System.IO.MemoryStream())
    {
        serializer.WriteObject(ms, this);
        ms.Position = 0;
        return serializer.ReadObject(ms);
    }
}

I have noticed that it doesn't copy the relationships. Is there any way to make this happen?


Solution

  • Simply use the constructor overload that accepts preserveObjectReferences, and set it to true:

    using System;
    using System.Runtime.Serialization;
    
    static class Program
    {
        public static T Clone<T>(T obj) where T : class
        {
            var serializer = new DataContractSerializer(typeof(T), null, int.MaxValue, false, true, null);
            using (var ms = new System.IO.MemoryStream())
            {
                serializer.WriteObject(ms, obj);
                ms.Position = 0;
                return (T)serializer.ReadObject(ms);
            }
        }
        static void Main()
        {
            Foo foo = new Foo();
            Bar bar = new Bar();
            foo.Bar = bar;
            bar.Foo = foo; // nice cyclic graph
    
            Foo clone = Clone(foo);
            Console.WriteLine(foo != clone); //true - new object
            Console.WriteLine(clone.Bar.Foo == clone); // true; copied graph
    
        }
    }
    [DataContract]
    class Foo
    {
        [DataMember]
        public Bar Bar { get; set; }
    }
    [DataContract]
    class Bar
    {
        [DataMember]
        public Foo Foo { get; set; }
    }