[英]Property's derived class is discarded(i.e., replaced with the base class) upon XML deserialization
我有一个游戏数据类,如下所示:
public class SaveGameData {
public virtual List<PropertyContainer> properties {get; set; }
}
这些类也是:
public class PropertyContainer {
public Property property {get; set; }//Could be set to DerivedProperty
}
public class Property {
public int BasePropertyData {get; set;}
}
public class DerivedProperty : Property {
public int DerivedPropertyData {get; set; }
}
我正在尝试在播放会话之间保存/加载此数据,为此过程使用了XML序列化/反序列化。
问题在于,在PropertyContainer类中,有时会使用派生属性来替代Property类,如下所示:
PropertyContainer container = new PropertyContainer();
container.property = derivedProperty;
当容器被序列化时,派生类及其特殊属性也被保存,这里没有问题。
这是序列化代码:
serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveGameData));
SaveGameData dataToSave = GetSaveGameData();
using (var stream = new StringWriter()) {
serializer.Serialize(stream, dataToSave);
...write to file...
}
序列化过程似乎正在正常进行,因为派生类已被正确识别并正确保存到XML文件中,因此XML输出如下所示:
<?xml version="1.0" encoding="utf-16"?>
<SaveGameData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<properties>
<PropertyContainer>
<property xsi:type="DerivedProperty">
<BasePropertyData>1</BasePropertyData>
<DerivedPropertyData>1</DerivedPropertyData>
</property>
</PropertyContainer>
</properties>
</SaveGameData>
但是,当反序列化XML文件时,将丢弃所有派生类。 这是反序列化代码:
SaveGameData result;
string data = ReadSaveGameData();
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(SaveGameData));
using (StringReader stream = new StringReader(savedGame)) {
result = (SaveGameData)serializer.Deserialize(stream);
}
这意味着在加载XML数据后,在派生属性(例如, saveGameData.properties[0].GetType()
,假设属性为DerivedProperty)上调用GetType()
)将产生基类,即Property
; 通过扩展,它会丢弃所有DerivedProperty的属性。 有问题。
PS:我尝试添加XmlInclude
属性,但未做任何更改:
[System.Xml.Serialization.XmlInclude(typeof(DerivedProperty))]
public class Property {
...
}
我该如何解决这个问题? 我的方法是否可行?
一种选择是切换到DataContractSerializer
。 然后使用KnownTypeAttribute
标识子类。
public class PropertyContainer {
public Property property {get; set; }//Could be set to DerivedProperty
}
[KnownType(typeof(DerivedProperty))]
public class Property {
public int BasePropertyData {get; set;}
}
public class DerivedProperty : Property {
public int DerivedPropertyData {get; set; }
}
用[XmlInclude(typeof(DerivedProperty))]
装饰Property
类应该已经起作用。 的确,没有它, XmlSerializer
甚至根本不会让您序列化DerivedProperty
!
以下程序是基于您的代码的有效示例。 请确认您的计算机上的控制台输出也为True
。 如果是这样,则需要确定代码与原始尝试的不同之处。 然后更新您的问题,以便我们进行更深入的探讨。
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
class Program
{
static void Main()
{
string savedGame = @"
<SaveGameData xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
<properties>
<PropertyContainer>
<property xsi:type='DerivedProperty'>
<BasePropertyData>1</BasePropertyData>
<DerivedPropertyData>1</DerivedPropertyData>
</property>
</PropertyContainer>
</properties>
</SaveGameData>";
XmlSerializer serializer = new XmlSerializer(typeof(SaveGameData));
SaveGameData result;
using (StringReader stream = new StringReader(savedGame))
{
result = (SaveGameData)serializer.Deserialize(stream);
}
Console.WriteLine(result.properties[0].property is DerivedProperty); // True
}
}
public class SaveGameData
{
public virtual List<PropertyContainer> properties { get; set; }
}
public class PropertyContainer
{
public Property property { get; set; }//Could be set to DerivedProperty
}
[XmlInclude(typeof(DerivedProperty))]
public class Property
{
public int BasePropertyData { get; set; }
}
public class DerivedProperty : Property
{
public int DerivedPropertyData { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.