c# - XML 反序列化带回空列表
问题描述
我有一个要在 XML 中序列化的能力对象字典 <id, abilityObj>。因为不能 XML Serialize 一个字典,所以我把它改成一个关于序列化的列表
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);
}
}
它正确序列化。即被保存的 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");
}
}
解决方案
许多序列化程序的工作方式是调用一个列表,如果序列化程序创建了列表(可能是因为它是,或者固定大小,如数组),Add
则实际上只将任何内容分配回设置器。所以想象一下序列化器在做什么:null
var list = obj.SomeProperty;
while (moreOfTheSame)
list.Add(ReadOneOfThose());
它从不调用 setter,因此其中的任何逻辑:无关紧要。你可能需要一个自定义列表类型,或者更简单:有一个简单的 POCO/DTO 模型,它只映射到序列化形状,没有有趣的逻辑,并在这个模型和你的域模型之间分别投影到序列化。
推荐阅读
- database - Docker如何管理数据库?
- python - 如何结束线程任务?
- tensorflow - 将张量流 tf.contrib.layers.layer_norm 转换为 tf2.0
- java - 如何从 Firebase 数据库 Android 获取子节点
- android - Flutter 在运行时更改抽屉标题图像
- python - Python PyQt5 QPlainTextEdit滚动条不显示句柄
- kubernetes - 如何使用一个负载均衡器为两个域的两个入口配置 nginx-ingress
- c++ - 二维数组操作和二分查找的实现
- c# - 在 C# 中公开泛型属性
- svelte - 组件中的异步操作没有返回