反序列化继承对象的集合

本文关键字:集合 对象 继承 反序列化 | 更新日期: 2023-09-27 18:05:39

我有一个xml文件,它的集合看起来像这样

<AbstractCollection>
    <ConcreteA name="Bob" age="4"/>
    <ConcreteB name="Tree" size="1" />
</AbstractCollection>

我知道如果我使用一个具体集合——即两个元素是相同的类型——在c#中使用标准的XML反序列化会很容易。不同的类型似乎使它更加困难。

是否有一种方法可以使用简单的xml反序列化来得到这个,或者我必须自己实现反序列化?

[为清晰添加]我应该补充说,xml已经存在,我不能改变它。我正在接收采用上述形式的xml格式的消息。更具体的例子是:

<Actions>
    <Walked name="Bob" distance="4"/>
    <Cycled name="Jane" gear="3rd" />
</Actions>

我最后想要的是一个"循环的"和一个"行走的"对象。为了让它更有趣,顺序很重要。

此外,我曾尝试在代码中使用XmlInclude属性,但当您序列化它时,通过更改xml(除非我一直在使用它当然是错误的)。

反序列化继承对象的集合

所以我找到了解决方案,感谢这个答案。

关键是使用XmlElementAttribute来改变不同类的序列化方式。

唯一奇怪的是,我发现我必须为列表创建一个包装器类,否则循环和行走的元素不会包装在根元素中。

我知道命名空间的东西还在那里,但我可以处理-获得派生类的问题已经解决了!

感谢大家的支持。

[Serializable]
public class Actions
{
    [XmlElementAttribute("Walked", typeof(WalkedAction))]
    [XmlElementAttribute("Cycled", typeof(CycledAction))]
    public List<Action> ActionList { get; set; }
}
[Serializable]
public abstract class Action
{
    [XmlAttribute]
    public string Name { get; set; }
}
[Serializable]
public class WalkedAction : Action
{
    [XmlAttribute]
    public int Distance { get; set; }
}
[Serializable]
public class CycledAction : Action
{
    [XmlAttribute]
    public string Gear { get; set; }
}

public class Program
{
    public static void Main(string[] args)
    {
        var actionList = new Actions();
        actionList.ActionList = new List<Action>();
        actionList.ActionList.Add(new WalkedAction { Name = "Bob", Distance = 4 });
        actionList.ActionList.Add(new CycledAction { Name = "Jane", Gear = "3rd" });
        var ser = new XmlSerializer(typeof(Actions));
        TextWriter w = new StringWriter();
        ser.Serialize(w, actionList);
        TextReader r = new StringReader(w.ToString());
        Actions result = (Actions) ser.Deserialize(r);
    }
}