2010-03-10 10 views
6

इस कोड का उपयोग करते हुए एक वस्तु को क्रमानुसार करने:क्लोन पूरी वस्तु ग्राफ

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); 
    } 
} 

मैं देखा है कि यह रिश्तों नकल नहीं करता है। क्या ऐसा करने का कोई तरीका है?

+0

मैं एक ही देखा, यह कुछ स्तरों में जा सकता है, लेकिन अधिकतर आप आंशिक और बेकार ग्राफ के साथ समाप्त होते हैं। – leppie

+0

@leppie - यह किया जा सकता है, हालांकि ;- –

उत्तर

16

, बस निर्माता अधिभार कि preserveObjectReferences स्वीकार करता है का उपयोग करें, और सेट यह:

+0

दुह! मुझे और संकेतों की तलाश करनी चाहिए! :) – leppie

+0

यह सबसे अच्छा तरीका होना चाहिए जैसा कि मैं देख सकता हूं ... thanx मार्क, लेकिन मुझे ऑब्जेक्ट.ऑब्जेक्ट 2.ऑब्जेक्ट 3 के साथ कोई समस्या है, क्या यह Serializer पर समस्या हो सकती है? –

1

या तो अपने कक्षाओं को [DataContract] के साथ एनोटेट करें या अपने बच्चे के प्रकार को डेटाकॉन्ट्रैक्टसेरियलाइज़र के निर्माता में जोड़ें।

var knownTypes = new List<Type> {typeof(Class1), typeof(Class2), ..etc..}; 
var serializer = new DataContractSerializer(GetType(), knownTypes); 
+0

थैंक्स, यह भी काम कर रहा है;) –

0

आप क्रमबद्धता/अक्रमांकन चरण के दौरान वस्तुओं पहचान बनाए रखने के लिए एक द्विआधारी 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

मुझे समझ में नहीं आता कि आपकी टिप्पणी मेरे उत्तर से कैसे संबंधित है ...? डारिन डिमिट्रोव – Seb

+1

द्वारा प्रदान किए गए कोड नमूने को देखें क्षमा करें @ सेब, लेकिन यह सही नहीं है। DataContractSerializer * उचित ग्राफ कॉपी कर सकते हैं, और एक बाइनरी serializer नहीं है। इसके विपरीत, यह सच नहीं है कि सभी बाइनरी serializers * आवश्यक रूप से ग्राफ की प्रतिलिपि बना सकते हैं। ग्राफ समर्थन और बाइनरी आउटपुट ऑर्थोगोनल अवधारणाएं हैं। –

1

एक गहरी क्लोन आप एक द्विआधारी serializer विचार कर सकते हैं करने के लिए

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; } 
} 
संबंधित मुद्दे