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.
精彩评论