为什么XmlSerializer的Deserialize调用我的类构造函数两次?

问题描述:

我使用这个代码:为什么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

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

它看起来像一个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

如果您已经通过公共属性公开了DataBaseManager,那么XmlSerializer将按照Sam的说法创建并反序列化它。现在第一次创建DataBaseManager它显然是在BasicProject的构造函数中完成的。当序列化程序尝试反序列化项目类时,它会调用默认的构造函数,这显然会创建一个数据库管理器。