将List <t>序列化为带继承的XML </t>

时间:2009-05-26 12:59:14

标签: c# .net xml-serialization

尝试将对象序列化为XML时遇到了一些问题。尝试序列化“配置文件”属性时出现问题,该属性是配置文件项列表。个人资料是我自己的类型。 理想情况下,配置文件类型应该是抽象的,但事实并非如此,因为XML序列化需要无参数的ctor。 Profiles属性包含“IncomeProfile”,“CostProfile”,“InvestmentProfile”等类型的项目,这些项目当然都来自Profile。

正如我所读到的,序列化它本身不受支持,因为XmlIncludeAttribute只允许一个继承类型。即。

[XmlInclude(typeof(IncomeProfile))]
public List<Profile> Profiles { get; set; }

解决此问题时的最佳做法是什么?我尝试过使用IXmlSerializable和反射的不同解决方案,但我似乎无法将每个配置文件反序列化为正确的类型(它们最终都使用Profile类型的ReadXml(XmlReader reader)方法,即使Visual Studio调试器说对象的类型是“IncomeProfile”或“CostProfile”。这是我当前的反序列化代码,它将xml反序列化为三个Profile对象,而不是两个IncomeProfile和一个CostProfile:

while(reader.MoveToContent() == XmlNodeType.Element && reader.LocalName == "Profile")
    {
        String type = reader["Type"];
        var project = (Profile)Activator.CreateInstance(Type.GetType(type));
        project.ReadXml(reader);

        reader.Read();
        this.Profiles.Add(p2);
    }

非常感谢任何想法或建议!

2 个答案:

答案 0 :(得分:10)

您可以使用多个包含属性 - 尽管它们通常是针对类型本身设置的:

using System;
using System.Collections.Generic;
using System.Xml.Serialization;
[XmlInclude(typeof(IncomeProfile))]
[XmlInclude(typeof(CostProfile))]
[XmlInclude(typeof(InvestmentProfile))]
public class Profile {
    public string Foo { get; set; }
}
public class IncomeProfile : Profile {
    public int Bar { get; set; }
}
public class CostProfile : Profile { }
public class InvestmentProfile : Profile { }
static class Program {
    static void Main() {
        List<Profile> profiles = new List<Profile>();
        profiles.Add(new IncomeProfile { Foo = "abc", Bar = 123 });
        profiles.Add(new CostProfile { Foo = "abc" });
        new XmlSerializer(profiles.GetType()).Serialize(Console.Out, profiles);
    }
}

答案 1 :(得分:3)

您只需使用多个[XmlInclude]属性。这很有效。