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

发布于 2024-11-02 15:45:19 字数 2580 浏览 1 评论 0原文

我正在使用此代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

乱了心跳 2024-11-09 15:45:19

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 your Project object (through the public property).

还如梦归 2024-11-09 15:45:19

看起来 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.

那小子欠揍 2024-11-09 15:45:19

如果您通过公共属性公开了 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 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文