XML 派生 class 在列表中的序列化,需要在父 class 上设置成员
XML serialization of derived class in a list, need to set member on parent class
作为一种爱好,我正在使用 XNA 和 C# 制作 2D RPG。我有一个名为 ObjectiveData 的 class。它的唯一成员是一个名为 objectiveID 的字符串。由此派生出各种其他 classes(GatherItemsObjectiveData、SpeakToNPCObjectiveData 等)——所有这些都应该存储与特定 objective 相关的自己的 objective 数据(gatherItemsObjectiveData 将保存关于收集哪些物品以及收集多少等)。它们之间唯一的共同点是 objectiveID,因此它在父 class.
中
当每个派生的 classes 都有自己的 objectiveID 变量时,我对这个工作进行了 XML 序列化,但我希望它在父 [=28] =] 这样我就可以在不知道 class 是什么派生的情况下获得 objectiveID 等。当我切换到将 objectiveID 放入父级时,它不再有效(说 XMl 元素 "objective" 未找到)。所以现在我想弄清楚如何让它在 XML 文件中将 objectiveID 传递给它的父级。
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace RpgLibrary.QuestClasses
{
public class ObjectivesData
{
[XmlArray("ObjectivesList")]
[XmlArrayItem("KillXObjectiveData", typeof(KillXObjectiveData))]
[XmlArrayItem("GatherXItemsObjectiveData", typeof(GatherXItemsObjectiveData))]
[XmlArrayItem("SpeakToNPCObjectiveData", typeof(SpeakToNPCObjectiveData))]
[XmlArrayItem("VisitAreaObjectiveData", typeof(VisitAreaObjectiveData))]
public List<ObjectiveData> ObjectivesList;
public ObjectivesData()
{
ObjectivesList = new List<ObjectiveData>();
}
}
[XmlInclude(typeof(KillXObjectiveData))]
[XmlInclude(typeof(GatherXItemsObjectiveData))]
[XmlInclude(typeof(SpeakToNPCObjectiveData))]
[XmlInclude(typeof(VisitAreaObjectiveData))]
public class ObjectiveData
{
public string objectiveID;
public ObjectiveData()
{
}
public ObjectiveData(string objectiveID)
{
this.objectiveID = objectiveID;
}
}
[XmlType(TypeName = "KillXObjectiveData")]
public class KillXObjectiveData : ObjectiveData
{
public string killTotal;
public string npcID;
public KillXObjectiveData()
{
}
public KillXObjectiveData(string killTotal, string npcID, string objectiveID)
: base(objectiveID)
{
this.killTotal = killTotal;
this.npcID = npcID;
}
}
[XmlType(TypeName = "GatherXItemsObjectiveData")]
public class GatherXItemsObjectiveData : ObjectiveData
{
public string gatherTotal;
public string itemID;
public GatherXItemsObjectiveData()
{
}
public GatherXItemsObjectiveData(string gatherTotal, string itemID, string objectiveID)
: base(objectiveID)
{
this.gatherTotal = gatherTotal;
this.itemID = itemID;
}
}
[XmlType(TypeName = "SpeakToNPCObjectiveData")]
public class SpeakToNPCObjectiveData : ObjectiveData
{
public string npcID;
public SpeakToNPCObjectiveData()
{
}
public SpeakToNPCObjectiveData(string npcID, string objectiveID)
: base(objectiveID)
{
this.npcID = npcID;
}
}
[XmlType(TypeName = "VisitAreaObjectiveData")]
public class VisitAreaObjectiveData : ObjectiveData
{
public string areaID;
public VisitAreaObjectiveData()
{
}
public VisitAreaObjectiveData(string areaID, string objectiveID)
: base(objectiveID)
{
this.areaID = areaID;
}
}
}
XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:QuestClasses="RpgLibrary.QuestClasses">
<Asset Type="QuestClasses:ObjectivesData">
<ObjectivesList>
<Item Type="QuestClasses:GatherXItemsObjectiveData">
<gatherTotal>5</gatherTotal>
<itemID>1</itemID>
<objectiveID>1</objectiveID>
</Item>
<Item Type="QuestClasses:KillXObjectiveData">
<killTotal>5</killTotal>
<npcID>900</npcID>
<objectiveID>2</objectiveID>
</Item>
</ObjectivesList>
</Asset>
</XnaContent>
最终结果应该是我得到了一个 ObjectiveData 列表,其中存储了所有派生的 class 对象,我只需要在父对象中正确设置 objectiveID class.
根据Everything you ever wanted to know about IntermediateSerializer
:
Base class members are serialized before data from the derived type
因此,您需要将 <objectiveID>
元素移动到预先存在的 XML 文件中其包含元素的开头。
作为一种爱好,我正在使用 XNA 和 C# 制作 2D RPG。我有一个名为 ObjectiveData 的 class。它的唯一成员是一个名为 objectiveID 的字符串。由此派生出各种其他 classes(GatherItemsObjectiveData、SpeakToNPCObjectiveData 等)——所有这些都应该存储与特定 objective 相关的自己的 objective 数据(gatherItemsObjectiveData 将保存关于收集哪些物品以及收集多少等)。它们之间唯一的共同点是 objectiveID,因此它在父 class.
中当每个派生的 classes 都有自己的 objectiveID 变量时,我对这个工作进行了 XML 序列化,但我希望它在父 [=28] =] 这样我就可以在不知道 class 是什么派生的情况下获得 objectiveID 等。当我切换到将 objectiveID 放入父级时,它不再有效(说 XMl 元素 "objective" 未找到)。所以现在我想弄清楚如何让它在 XML 文件中将 objectiveID 传递给它的父级。
C#代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace RpgLibrary.QuestClasses
{
public class ObjectivesData
{
[XmlArray("ObjectivesList")]
[XmlArrayItem("KillXObjectiveData", typeof(KillXObjectiveData))]
[XmlArrayItem("GatherXItemsObjectiveData", typeof(GatherXItemsObjectiveData))]
[XmlArrayItem("SpeakToNPCObjectiveData", typeof(SpeakToNPCObjectiveData))]
[XmlArrayItem("VisitAreaObjectiveData", typeof(VisitAreaObjectiveData))]
public List<ObjectiveData> ObjectivesList;
public ObjectivesData()
{
ObjectivesList = new List<ObjectiveData>();
}
}
[XmlInclude(typeof(KillXObjectiveData))]
[XmlInclude(typeof(GatherXItemsObjectiveData))]
[XmlInclude(typeof(SpeakToNPCObjectiveData))]
[XmlInclude(typeof(VisitAreaObjectiveData))]
public class ObjectiveData
{
public string objectiveID;
public ObjectiveData()
{
}
public ObjectiveData(string objectiveID)
{
this.objectiveID = objectiveID;
}
}
[XmlType(TypeName = "KillXObjectiveData")]
public class KillXObjectiveData : ObjectiveData
{
public string killTotal;
public string npcID;
public KillXObjectiveData()
{
}
public KillXObjectiveData(string killTotal, string npcID, string objectiveID)
: base(objectiveID)
{
this.killTotal = killTotal;
this.npcID = npcID;
}
}
[XmlType(TypeName = "GatherXItemsObjectiveData")]
public class GatherXItemsObjectiveData : ObjectiveData
{
public string gatherTotal;
public string itemID;
public GatherXItemsObjectiveData()
{
}
public GatherXItemsObjectiveData(string gatherTotal, string itemID, string objectiveID)
: base(objectiveID)
{
this.gatherTotal = gatherTotal;
this.itemID = itemID;
}
}
[XmlType(TypeName = "SpeakToNPCObjectiveData")]
public class SpeakToNPCObjectiveData : ObjectiveData
{
public string npcID;
public SpeakToNPCObjectiveData()
{
}
public SpeakToNPCObjectiveData(string npcID, string objectiveID)
: base(objectiveID)
{
this.npcID = npcID;
}
}
[XmlType(TypeName = "VisitAreaObjectiveData")]
public class VisitAreaObjectiveData : ObjectiveData
{
public string areaID;
public VisitAreaObjectiveData()
{
}
public VisitAreaObjectiveData(string areaID, string objectiveID)
: base(objectiveID)
{
this.areaID = areaID;
}
}
}
XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<XnaContent xmlns:QuestClasses="RpgLibrary.QuestClasses">
<Asset Type="QuestClasses:ObjectivesData">
<ObjectivesList>
<Item Type="QuestClasses:GatherXItemsObjectiveData">
<gatherTotal>5</gatherTotal>
<itemID>1</itemID>
<objectiveID>1</objectiveID>
</Item>
<Item Type="QuestClasses:KillXObjectiveData">
<killTotal>5</killTotal>
<npcID>900</npcID>
<objectiveID>2</objectiveID>
</Item>
</ObjectivesList>
</Asset>
</XnaContent>
最终结果应该是我得到了一个 ObjectiveData 列表,其中存储了所有派生的 class 对象,我只需要在父对象中正确设置 objectiveID class.
根据Everything you ever wanted to know about IntermediateSerializer
:
Base class members are serialized before data from the derived type
因此,您需要将 <objectiveID>
元素移动到预先存在的 XML 文件中其包含元素的开头。