如何在Xml中序列化派生类?

Dar*_*Zon 2 c# xml serialization xml-serialization

想象一下这是我的场景:

public abstract class Foo
{
    public abstract int X { get; set; }
}

public class FooA : Foo
{
    public override int X { get; set; }
    public int Y { get; set; }
}

public class FooB : Foo
{
    public override int X { get; set; }
    public int Z { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是一个服务,我有一些序列化的对象.

public class FooService
{
    public List<Foo> GetModels()
    {
        return new List<Foo>()
        {
            new FooA() { X = 3, Y = 6 },
            new FooB() { X = 5, Z = 10 }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我无法序列化我的对象的方法,它抛出异常.我想序列化派生类.

    private void SerializeObjects()
    {
        FooService service = new FooService();
        var a = service.GetModels();

        XmlSerializer x = new XmlSerializer(a.GetType());
        TextWriter writer = new StreamWriter("A.xml");

        x.Serialize(writer, a);
        writer.Close();
    }
Run Code Online (Sandbox Code Playgroud)

Eri*_* J. 12

您必须告诉序列化器有关派生类型的信息

[XmlInclude(typeof(FooA))]
[XmlInclude(typeof(FooB))]
public abstract class Foo
{
    public abstract int X { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这是真正有用的.Net异常之一.如果你看一下InnerException,你会看到

不期望FooA类型.使用XmlInclude或SoapInclude属性指定静态未知的类型.

UPDATE

根据您对不同模块中许多派生类型的注释,您还可以在创建序列化程序时而不是在编译时在运行时指定派生类型:

如何动态添加XmlInclude属性