为什么 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
实现了 IXmlSerialized
,但 ReadXml
仅在之后调用两个 DataBaseManager 都已创建,所以我认为我没有做错什么。
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 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
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
Project
类是否有一个公共属性,可以将_DataBase
字段公开给序列化器?XmlSerializer 将实例化一个新的 DataBaseManager 对象并将其完全反序列化,然后将其分配回您的 Project 对象(通过公共属性)。
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 yourProject
object (through the public property).看起来 Project 类型的构造函数创建了 DataBaseManager 的实例。
在您的情况下,当反序列化 Project 类型的实例时,Project 的构造函数会创建一个 DataBaseManager 实例。然后,反序列化器创建另一个实例 DataBaseManager,用于反序列化 Project 字段之一。
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.
如果您通过公共属性公开了 DataBaseManager,那么 XmlSerializer 将按照 Sam 的说法创建并反序列化它。现在,第一次创建
DataBaseManager
时,它显然是在BasicProject
的构造函数中完成的。当序列化程序尝试反序列化项目类时,它会调用默认构造函数,该构造函数显然会创建一个数据库管理器。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 theDataBaseManager
is created it's apparently done in the constructor ofBasicProject
. When the serializer tries to deserialize the project class it calls the default constructor which apparently creates a database manager.