开发者

Why is XmlSerializer's Deserialize calling my class constructor twice?

I'm using this code:

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

to deserialize my Project class. Inside that class there is another class called DataBaseManager that is defined this way:

private DataBaseManager _DataBase = new DataBaseManager();

DataBaseManager implements IDisposable and needs to be disposed for each time is created. But for some reason Deserialize is creating a DataBaseManager twice and not disposing any of them (of course one of them must not be disposed because is the one I'll use).

Here is the call stack for the first call:

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  

And this is the second call:

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 byte开发者_JAVA技巧s  
[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  

Also, DataBaseManager implements IXmlSerializable, but ReadXml is only called after both DataBaseManager have been created, so I don't think I'm doing anything wrong there.


Does the Project class have a public property which would expose the _DataBase field to the serializer?

The XmlSerializer will instantiate a new DataBaseManager object and deserialize it completely before assigning it back to your Project object (through the public property).


It looks like a constructor for the Project type creates an instance of DataBaseManager.

In your case the constructor of Project creates one instance of DataBaseManager when an instance of the Project type is deserialized. Then another instance DataBaseManager is created by the deserializer that deserializes one of Project fields.


If you have exposed the DataBaseManager via a public property then the XmlSerializer will create and deserialize it as Sam said. Now the first time the DataBaseManager is created it's apparently done in the constructor of BasicProject. When the serializer tries to deserialize the project class it calls the default constructor which apparently creates a database manager.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜