2011-03-03 83 views
1

爲什麼在反序列化之後,對象引用與序列化之前不同。序列化和反序列化後的對象引用

確定讓我解釋一下這個

我有一個字符串

字符串測試= 「的TestString」;

現在我做Serilization

    DataContractJsonSerializer _DataContractJsonSerializer 
      = new DataContractJsonSerializer(typeof(string)); 

         MemoryStream ms = new MemoryStream(); 
      _DataContractJsonSerializer.WriteObject(ms, test); 
      var jsonString = Encoding.Default.GetString(ms.ToArray()); 

現在我做DeSerilization從jsonstring到實際值

 MemoryStream ms1 = 
      new MemoryStream(Encoding.Unicode.GetBytes(jsonString)); 
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(string)); 
      string DeseriliaedStrring = serializer.ReadObject(ms1) as string; 

在這裏DeseriliaedStrring我得到了實際價值,但如果我檢查有沒有引用它們不相等

bool isReferenceEqual = object.ReferenceEquals(DeseriliaedStrring, test); 
+0

他們不應該引用相同的對象,一個是源和其他(反序列化)是傳真,他們是可比較的,但沒有一個是相同的。 – 2011-03-03 13:24:39

回答

1

當您序列化和反序列化一個對象時,反序列化將創建一個基於序列化數據的實例。這當然不是原來的實例,這看起來很合理。畢竟,你有以下過程:

  • 你有一個對象實例
  • 您創建一個字符串實例,它是該對象實例
  • 您創建一個基於序列化的數據對象實例的表示字符串

如果你考慮到原來的實例可能已經變異,使反序列化可以在另一個過程中發生的,即使是在另一臺機器,它變得很清楚,反序列化不可能回到原來的instanc即

在這種特殊情況下,當對象是String,你能想象得到的字符串實習將使系統重新使用舊實例(如果反序列化發生相同的AppDomain內)。但是這可能需要DataContractJsonSerializer意識到這一點,這會使它不必要的複雜。

*)我其實不太確定什麼系統的一部分照顧字符串interning。

+0

如果我在deserilization之後需要相同的引用,該怎麼做,是否有任何方法可以做到這一點 – 2011-03-03 13:42:48

+0

@slash:在AppDomain中總有一種方法,它更多的是你願意犧牲多少工作和內存的問題。更重要的問題是:*爲什麼*? – 2011-03-03 13:45:21

2

序列化創建對象的值的副本。反序列化使用複製的值創建一個全新的實例。

編輯迴應您的評論如下:反序列化不會調用構造函數。如果這是一個問題,則用ISerializable覆蓋。這將基於對ISerializable.GetObjectData的調用進行序列化,然後調用具有SerializationInfoStreamingContext字段的特定構造函數。

+0

好吧這個例子與字符串有關,但是如果我爲任何自定義類做了這個serilization和deserilization ...如果我爲了創建新的實例,我必須調用這個類的結構體,因此我必須調用它...... – 2011-03-03 13:30:37

+0

@slash shogde反序列化不會調用默認構造函數。該對象正在直接從字節流創建。 – 2011-03-03 13:34:51

+0

謝謝非常感謝,你的答案是非常正確的,我只增加了點,因爲becoz已經檢查了上面的答案.. plz不介意 – 2011-03-03 13:41:27