2010-10-26 9 views
6

जैसा कि एमएसडीएन here बताता है, यह कर सकता है। लेकिन मैंने mscorlib कोड खोदने में 2 घंटे बिताए हैं, क्योंकि कुछ मामलों में बाइनरीफॉर्मेटर ने मेरी विधि को ऑनडिसेरियलाइज्ड BEFORE deserialization constructor के साथ चिह्नित किया है। जो है, आदेशIDDerialializationCallback इंटरफेस के बजाय OnDeserializedAttribute का उपयोग किया जा सकता है?

OnDeserializing(StreamingContext context) 
OnDeserialized(StreamingContext context) 
.ctor(SerializationInfo info, StreamingContext context) 

हालांकि मैं यह

OnDeserializing(StreamingContext context) 
.ctor(SerializationInfo info, StreamingContext context) 
OnDeserialized(StreamingContext context) 

और अंतिम बिंदु होने की उम्मीद कर रहा था था। जब मैंने IDeserializationCallback इंटरफ़ेस को कार्यान्वित किया, तो इसकी विधि ऑनडिसेरियलाइजेशन को कन्स्ट्रक्टर के बाद बुलाया गया था, जैसा कि मैं चाहता था और अपेक्षित था।

मैंने इसे कुछ साधारण वर्ग संरचना पर पुन: उत्पन्न करने की कोशिश की, लेकिन वहां सब ठीक काम किया। हमारी प्रोजेक्ट में ऑरेंज ग्राफ को क्रमबद्ध किया जाना बहुत जटिल है, इसलिए मुझे नहीं पता कि खोदना कहां है। परावर्तक के साथ mscorlib कोड का निरीक्षण करने से बहुत मदद नहीं मिली - समस्या का पता लगाने के लिए deserialization कोड मेरे लिए बहुत जटिल है।

तो, क्या कोई जानता है कि ऐसी समस्या का कारण क्या हो सकता है? हम इस धारणा का उपयोग करते हैं कि ऑनडिसेरियलाइज्ड को कई अन्य स्थानों में कन्स्ट्रक्टर से पहले बुलाया जाता है, इसलिए अब मुझे डर है कि यह बहुत विश्वसनीय नहीं है ...

धन्यवाद!

उत्तर

5

आखिरकार, मेरे पास अपने स्वयं के प्रश्न का उत्तर है, अगर कोई दिलचस्पी लेता है। इस पोस्ट के अंत में उदाहरण पर विचार करें। दो वर्ग हैं, जिनके उदाहरण एक-दूसरे के संदर्भ हैं। ऐसी परिस्थितियों में ऐसी कोई संभावना नहीं है कि दोनों उदाहरणों के रचनाकारों को निर्जलित करने के लिए निर्मित वस्तुओं के साथ पारित किया जा सके। तो सीरिएलाइज़र पहले रचनाकारों में से एक को दूसरे प्रकार के एक असंवैधानिक उदाहरण को पास करता है और उसके बाद उस ऑब्जेक्ट के कन्स्ट्रक्टर को कॉल करता है, जिससे इसे पहले प्रकार के उदाहरण का निर्माण किया जाता है। इस तरह से यह ऑब्जेक्ट कनेक्शन को पुनर्स्थापित करने में हमारी सहायता करता है, इसलिए यह वास्तव में सबसे अच्छा है!

अगला, ऐसे मामलों में OnDeserializing और OnDeserialized कॉलबैक के रूप में मैं प्रश्न में बताया कहा जा सकता है, जबकि IDeserializationCallback की OnDeserialization विधि हमेशा के बाद पूरा वस्तुओं ग्राफ deserialized कर दिया गया है कहा जाता है, बिल्कुल के रूप में वह अपने विनिर्देश में कहा गया है।

उपर्युक्त सभी को ध्यान में रखते हुए, मुझे IDeserializationCallback इंटरफ़ेस का उपयोग करने के लिए सबसे अच्छा लगता है ताकि मुझे किसी भी पोस्ट-डिसेरियलाइजेशन प्रोसेसिंग की आवश्यकता हो। उस मामले में मुझे यकीन है कि सभी वस्तुओं के लिए रचनाकारों को बुलाया जाता है और मैं 'सुरक्षित' तरीके से आवश्यक संशोधन कर सकता हूं।

 [Serializable] 
     class One :ISerializable, IDeserializationCallback 
     { 
      public Two m_two; 
      public One() {} 
      public One(SerializationInfo info, StreamingContext context) 
      { 
       var two = (Two)info.GetValue("m_two", typeof(Two)); 
       m_two = two; 
      } 
      public void GetObjectData(SerializationInfo info, StreamingContext context) 
      { 
       info.AddValue("m_two", m_two); 
      } 
      private bool m_onDeserializing; 
      private bool m_onDeserialized; 
      private bool m_callback; 
      public void OnDeserialization(object sender) 
      { 
       m_callback = true; 
      } 
      [OnDeserializing] 
      void OnDeserializing(StreamingContext context) 
      { 
       m_onDeserializing = true; 
      } 

      [OnDeserialized] 
      void OnDeserialized(StreamingContext context) 
      { 
       m_onDeserialized = true; 
      } 
     } 

     [Serializable] 
     private class Two : ISerializable, IDeserializationCallback 
     { 
      public Two(){} 
      public One m_one; 
      public Two(SerializationInfo info, StreamingContext context) 
      { 
       var one = (One)info.GetValue("m_one", typeof(One)); 
       m_one = one; 
      } 
      public void GetObjectData(SerializationInfo info, StreamingContext context) 
      { 
       info.AddValue("m_one", m_one); 
      } 
      private bool m_onDeserializing; 
      private bool m_onDeserialized; 
      private bool m_callback; 
      public void OnDeserialization(object sender) 
      { 
       m_callback = true; 
      } 
      [OnDeserializing] 
      void OnDeserializing(StreamingContext context) 
      { 
       m_onDeserializing = true; 
      } 
      [OnDeserialized] 
      void OnDeserialized(StreamingContext context) 
      { 
       m_onDeserialized = true; 
      } 
     } 

     [STAThread] 
     static void Main() 
     { 
      var one = new One(); 
      one.m_two = new Two(); 
      one.m_two.m_one = one; 

      BinaryFormatter formatter = new BinaryFormatter(); 
      MemoryStream mss =new MemoryStream(); 
      formatter.Serialize(mss, one); 
      mss.Position = 0; 
      var deserialize = formatter.Deserialize(mss); 
     } 
संबंधित मुद्दे

 संबंधित मुद्दे