【问题标题】:C# XML serialization with derived objectsC# XML 序列化与派生对象
【发布时间】:2014-08-26 17:38:07
【问题描述】:

我一直在使用本教程系列在 XNA 中编写 2D RPG:http://xnagpa.net/xna4rpg.php

作者从未完成,但我继续前进并取得了很大进展(碰撞检测、NPC 路径、库存等)。现在我正在开发一个事件系统(转换到不同的级别,与 NPC 交互,任务等)。这是非常简单的,但这是我最初的设置:

public abstract class GameEvent
{
    #region Field Region

    protected Point eventPosition;

    #endregion

    #region Property Region

    public Point EventPosition
    {
        get { return eventPosition; }
    }

    #endregion

    #region Constructor Region

    public GameEvent()
    {

    }

    public GameEvent(Point eventPosition)
    {
        this.eventPosition = eventPosition;
    }

    #endregion
}

public class LevelTransitionEvent : GameEvent
{
    #region Field Region

    public Point teleportPosition;
    public string mapName;

    #endregion

    #region Constructor Region

    public LevelTransitionEvent()
    {

    }

    public LevelTransitionEvent(Point eventPosition, Point teleportPosition, 
        string mapName)
        : base(eventPosition)
    {
        this.teleportPosition = teleportPosition;
        this.mapName = mapName;
    }

    #endregion
}

我使用教程中启动的关卡编辑器来制作地图、添加 NPC,然后添加事件。它的工作方式是使用 XML 序列化/反序列化。它适用于一切(添加瓷砖、NPC、宝箱),但现在我正在尝试添加这些事件,从关卡转换事件开始。

这是教程中处理序列化的代码:

static class XnaSerializer
{
    public static void Serialize<T>(string filename, T data)
    {
        XmlWriterSettings settings = new XmlWriterSettings();
        settings.Indent = true;

        using (XmlWriter writer = XmlWriter.Create(filename, settings))
        {
            IntermediateSerializer.Serialize<T>(writer, data, null);                
        }
    }

    public static T Deserialize<T>(string filename)
    {
        T data;

        using (FileStream stream = new FileStream(filename, FileMode.Open))
        {
            using (XmlReader reader = XmlReader.Create(stream))
            {
                data = IntermediateSerializer.Deserialize<T>(reader, null);
            }
        }

        return data;
    }
}

序列化关卡:

  XnaSerializer.Serialize<LevelData>(LevelPath + levelData.LevelName + ".xml", levelData);

现在我只是想让它工作,所以我包含了一个简单的事件:

        levelData.GameEvents.Add(new LevelTransitionEvent(new Point(0,0), new Point(5,5), "temp"));

levelData.GameEvents 是 GameEvent 类型的 List。

这是 XML 输出:

 <?xml version="1.0" encoding="utf-8"?>
 <XnaContent xmlns:WorldClasses="RpgLibrary.WorldClasses"                                                                            xmlns:EventClasses="XRpgLibrary.EventClasses">
 <Asset Type="WorldClasses:LevelData">
 <LevelName>test 6</LevelName>
 <MapName>6</MapName>
 <MapWidth>100</MapWidth>
 <MapHeight>100</MapHeight>
 <Characters />
 <Chests />
 <GameEvents>
  <Item Type="EventClasses:LevelTransitionEvent">
    <teleportPosition>5 5</teleportPosition>
    <mapName>temp</mapName>
  </Item>
</GameEvents>
<TrapNames />
 </Asset>
 </XnaContent>

由于某种原因,未包含基类变量 eventPosition。我是否必须添加一些附加功能才能使基类成员数据也包含在 xml 序列化中?谢谢

【问题讨论】:

  • 我不是 XNA 方面的专家,但是当使用标准的 .NET XmlSerializer(我假设 IntermediateSerializer 与此类似)时,所有要序列化/反序列化的属性都必须有一个 public getter 和 setter。试着试一试,看看会产生什么。您的其他字段是公共的,因为它们是字段(尽管我也会将它们设为属性)具有读写能力。有关详细信息,请参见此处:stackoverflow.com/questions/575432/…
  • 你说得对,我刚刚将 eventPosition 字段更改为 public,它工作正常。感谢那。我不希望我的字段像这样公开,我只是创建临时类来测试这个新功能。再次感谢!

标签: c# inheritance serialization xna xml-serialization


【解决方案1】:

使用标准 .NET XmlSerializer(与 IntermediateSerializer 类似)时,所有要序列化/反序列化的属性都必须具有公共 getter 和 setter。

有关详细信息,请参见此处:Why isn't my public property serialized by the XmlSerializer?

MS 文档也有一个关于使用 XNA 序列化游戏数据的简单教程:http://msdn.microsoft.com/en-us/library/bb203924.aspx(注意这里直接使用了XmlSerializer)。

通过将您的属性更改为:

   public Point EventPosition
    {
        get { return eventPosition; }
        set { eventPosition = value; }
    }

您现在应该在序列化的输出结果中看到它。

【讨论】:

    【解决方案2】:

    默认情况下,IntermediateSerializer 仅使用公共 get 和 set 访问器序列化公共字段或属性。要让它序列化较少的公共字段,请使用 [ContentSerializer] 属性:

    [ContentSerializer]
    public Point EventPosition
    {
        get { return eventPosition; }
    }
    

    欲了解更多信息,请参阅:Everything you ever wanted to know about IntermediateSerializer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2012-09-09
      相关资源
      最近更新 更多