Clone Whole Object Graph

后端 未结 4 1710
心在旅途
心在旅途 2020-12-29 00:15

While using this code to serialize an object:

public object Clone()
{
    var serializer = new DataContractSerializer(GetType());
    using (var ms = new Sys         


        
相关标签:
4条回答
  • 2020-12-29 00:28

    You need a binary serializer to preserve objects identity during the serialization/deserialization step.

    0 讨论(0)
  • 2020-12-29 00:37

    Either annotate your classes with [DataContract] or add your child types in the constructor of DatacontractSerializer.

    var knownTypes = new List<Type> {typeof(Class1), typeof(Class2), ..etc..};
    var serializer = new DataContractSerializer(GetType(), knownTypes);
    
    0 讨论(0)
  • 2020-12-29 00:41

    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; }
    }
    
    0 讨论(0)
  • 2020-12-29 00:41

    To perform a deep clone you might consider using a binary serializer:

    public static object CloneObject(object obj)
    {
        using (var memStream = new MemoryStream())
        {
            var binaryFormatter = new BinaryFormatter(
                 null, 
                 new StreamingContext(StreamingContextStates.Clone));
            binaryFormatter.Serialize(memStream, obj);
            memStream.Seek(0, SeekOrigin.Begin);
            return binaryFormatter.Deserialize(memStream);
        }
    }
    
    0 讨论(0)
提交回复
热议问题