繁体   English   中英

XML反序列化时,将丢弃属性的派生类(即,用基类替换)

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM