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 文件中其包含元素的开头。