【问题标题】:XML deserialize brings back empty listXML 反序列化带回空列表
【发布时间】:2021-08-07 00:29:23
【问题描述】:

我有一个能力对象字典 我试图在 XML 中序列化。因为不能对字典进行XML序列化,所以我把它改成一个关于序列化的列表

public class BattleSerializable : TyrantSerializable
{
    [XmlIgnoreAttribute]
    [NonSerialized]
    [DoNotSerialize]
    public Dictionary<int, AbilityObjectSerializable> battleObjects;
    
    public List<AbilityObjectSerializable> serializedBattleObjects
    {
        get
        {
            if (battleObjects == null)
            {
                battleObjects = new Dictionary<int, AbilityObjectSerializable>();
            }

            return battleObjects.Select(x => x.Value).ToList();
        }
        set
        {
            battleObjects = value.ToDictionary(x => x.entityId, x => x);
        }
    }

它正确序列化。 IE。保存的 XML 有意义

<BattleSerializable>
    ...
    <serializedBattleObjects>
      <AbilityObjectSerializable xmlns:d3p1="http://www.w3.org/2001/XMLSchema-instance" d3p1:type="FireballObject">
         <hexDirection>southeast</hexDirection>
         <gridX>0</gridX>
         <gridZ>7</gridZ>
         <entityId>3</entityId>
         <lastAnimation>STATUE</lastAnimation>
         <timer>0</timer>
         <abilityPos>2</abilityPos>
         <abilityType>FIREBALL</abilityType>
         <health>100</health>
         <tilesPerTurn>2</tilesPerTurn>
         <jump>1</jump>
         <fall>99</fall>
         <damage>5</damage>
         <lineTraversed>
            <xDisplace>1</xDisplace>
            <zDisplace>-2</zDisplace>
            <endTileFacing>east</endTileFacing>
         </lineTraversed>
         <moveDirection>
            <xDisplace>1</xDisplace>
            <zDisplace>-2</zDisplace>
            <endTileFacing>east</endTileFacing>
         </moveDirection>
      </AbilityObjectSerializable>
    </serializedBattleObjects>
</BattleSerializable>

但是当我尝试加载此 XML 并将其转换为实际的 C# 对象时,由于某种原因,此列表为空,导致应用程序崩溃。

我错过了什么?此类中的所有其他列表都可以正确序列化/反序列化。

我的加载代码:

public BattleSerializable Load(string path)
{
    var serializer = new XmlSerializer(typeof(BattleSerializable));
    try
    {
        using (var stream = new FileStream(path, FileMode.Open))
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(stream);
            string xmlString = xmlDoc.InnerXml;
            BattleSerializable bs = (BattleSerializable)this.LoadFromXML(xmlString);
            return bs;
        }
    }
    catch (Exception e)
    {
        throw new SettingLoadException("Settings failed validation");
    }
}

【问题讨论】:

  • 最好的调试方式是向类中添加数据并序列化。将序列化的 xml 与您尝试导入的实际 xml 进行比较。

标签: c# xml serialization game-development


【解决方案1】:

许多序列化程序的工作方式是在列表上调用Add,只有在序列化程序创建了列表时才真正将任何内容分配给setter(可能是因为它是null,或固定大小,例如数组)。所以想象一下序列化器在做什么:

var list = obj.SomeProperty;
while (moreOfTheSame)
   list.Add(ReadOneOfThose());

从不调用setter,所以其中的任何逻辑:无关紧要。您可能需要一个自定义列表类型,或者更简单:有一个很好的简单 POCO/DTO 模型,只是映射到没有有趣逻辑的序列化形状,并在此模型和您的模型之间进行项目域模型单独进行序列化。

【讨论】:

  • 完美。帮助我了解发生了什么。制作自定义词典
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多