2011-04-22 35 views
1

我使用這個代碼:爲什麼XmlSerializer的Deserialize調用我的類構造函數兩次?

using (Stream stream = File.Open(fileName, FileMode.Open)) 
{ 
    XmlSerializer xmlFormatter = new XmlSerializer(typeof(Project)); 
    result = (Project)xmlFormatter.Deserialize(stream); 
} 

反序列化我Project類。該類內還有另一種稱爲DataBaseManager類定義是這樣的:

private DataBaseManager _DataBase = new DataBaseManager(); 

DataBaseManager實現IDisposable需要對於每次創建以被設置。但由於某種原因,Deserialize正在創建一個DataBaseManager兩次,而不是處置其中的任何一個(當然,其中一個不能丟棄,因爲是我會使用的)。

這裏是第一次調用調用堆棧:

HS Dll.exe!Player.DataBaseManager.DataBaseManager() Line 42 C# 
HS Dll.exe!Player.Project.BasicProject.BasicProject() Line 108 + 0x15 bytes C# 
HS Dll.exe!WebScraperAndPlayer.Project.Project() Line 23 + 0x8 bytes C# 
xdowmsmh!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderProject.Read32_Project(bool isNullable, bool checkType) + 0x178 bytes 
xdowmsmh!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderProject.Read33_Project() + 0xb8 bytes 
[Native to Managed Transition] 
System.Xml.dll!System.Xml.Serialization.TempAssembly.InvokeReader(System.Xml.Serialization.XmlMapping mapping, System.Xml.XmlReader xmlReader, System.Xml.Serialization.XmlDeserializationEvents events, string encodingStyle) + 0xc1 bytes 
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader xmlReader, string encodingStyle, System.Xml.Serialization.XmlDeserializationEvents events) + 0xc8 bytes 

這是第二個電話:

HS Dll.exe!Player.DataBaseManager.DataBaseManager() Line 42 C# 
xdowmsmh!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderProject.Read32_Project(bool isNullable, bool checkType) + 0x2a53 bytes 
xdowmsmh!Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderProject.Read33_Project() + 0xb8 bytes 
[Native to Managed Transition] 
System.Xml.dll!System.Xml.Serialization.TempAssembly.InvokeReader(System.Xml.Serialization.XmlMapping mapping, System.Xml.XmlReader xmlReader, System.Xml.Serialization.XmlDeserializationEvents events, string encodingStyle) + 0xc1 bytes 
System.Xml.dll!System.Xml.Serialization.XmlSerializer.Deserialize(System.Xml.XmlReader xmlReader, string encodingStyle, System.Xml.Serialization.XmlDeserializationEvents events) + 0xc8 bytes 

此外,DataBaseManager實現IXmlSerializable,但ReadXml後兩者DataBaseManager有隻叫被創建,所以我不認爲我在那裏做錯了什麼。

+1

這是一個「活動」對象,因爲它創建了一個「IDisposable」實例。這不是你應該序列化和反序列化的東西,恕我直言。 – 2011-04-22 21:54:51

回答

3

Project類是否有一個公開屬性,將_DataBase字段暴露給序列化程序?

XmlSerializer將實例化一個新的DataBaseManager對象,並在將其分配給Project對象(通過公共屬性)之前將其完全反序列化。

+0

這很有道理。我想我必須在setter中放置舊的'DataBaseManager'。並確保整個項目中的任何其他課程都沒有發生這種情況! – Juan 2011-04-22 21:49:52

+0

等一下。我認爲這是不對的。如果A類擁有需要處置的財產B,誰應該負責處理B?我會認爲誰創建它,但XmlSerializer不會這樣做...... – Juan 2011-04-22 22:00:48

0

它看起來像一個Project類型的構造函數創建DataBaseManager的一個實例。

在你的情況下,項目類型的一個實例被反序列化時,Project的構造函數創建一個DataBaseManager的實例。然後另一個實例DataBaseManager由反序列化器來創建,該反序列化器反序列化一個Project字段。

+0

您可能需要標記一個字段,它包含NonSerializableAttribute的DataBaseManager對象。然後它將僅由Project類構造函數創建,並且不會由反序列化程序第二次創建。 – Dennis 2011-04-22 22:22:46

+0

一個更正。由於堆棧DataBasaManager由ProjectBase構造函數創建,該構造函數由Project構造函數調用。 – Dennis 2011-04-22 22:24:36

0

如果您已經通過公共屬性公開了DataBaseManager,那麼XmlSerializer將按照Sam的說法創建並反序列化它。現在第一次創建DataBaseManager它顯然是在BasicProject的構造函數中完成的。當序列化程序嘗試反序列化項目類時,它會調用默認的構造函數,這顯然會創建一個數據庫管理器。

相關問題