C# 使用派生类型的XML序列化

C# 使用派生类型的XML序列化,c#,xml-serialization,derived-class,C#,Xml Serialization,Derived Class,我在让我的序列化程序工作时又遇到了一个问题。我有一个基类a和一个派生类B: class Program { static void Main(string[] args) { A foo = new B(); // determine that the class B overrides A XmlAttributeOverrides overrides = new XmlAttributeOverrides();

我在让我的序列化程序工作时又遇到了一个问题。我有一个基类a和一个派生类B:

class Program
{
    static void Main(string[] args)
    {
        A foo = new B();

        // determine that the class B overrides A
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();
        overrides.Add(typeof(A), new XmlAttributes
        {
            XmlElements = { new XmlElementAttribute("B", typeof(B)) }
        });

        XmlSerializer ser = new XmlSerializer(typeof(A), overrides);
        ser.Serialize(new XmlTextWriter("test.xml", Encoding.Default), foo);

    }
}

public class A { public int a;}
public class B : A { public int b;}
但当我运行这个小程序时,我得到了一个异常

不能为类型ConsoleApplication1.A指定XmlRoot和XmlType属性


但是我从来没有确定类A的根或类型属性,所以我真的对这个消息感到困惑。在幕后有什么我必须说明的吗?我所要做的就是序列化一个B实例,该实例只需向A的定义中添加一些属性。

它就在您收到的错误消息中

不能为类型ConsoleApplication1.A指定XmlRoot和XmlType属性

必须为输出xml文档指定根元素

替换

overrides.Add(typeof(A), new XmlAttributes

你可能还需要更换

new XmlSerializer(typeof(A), overrides);     


有关覆盖的更多信息和示例,请访问。

我终于找到了两种解决方案:

第一:

...
XmlSerializer ser = new XmlSerializer(typeof(A));
ser.Serialize(new XmlTextWriter("test.xml", Encoding.Default), foo);
...         

[System.Xml.Serialization.XmlRoot("Root", Namespace = "DefaultNS")]
[System.Xml.Serialization.XmlInclude(typeof(B))]
public class A { public int a;}

[System.Xml.Serialization.XmlRoot(Namespace = "CustomNS")]
public class B : A { public int b;}
2号(除Ondrejs解决方案外):


与第一个解决方案相比,第二个解决方案的缺点是,您可能看不到XML文档中的属性来自哪里(来自defaultNS或customNS),因为您无法指定任何customNS。

我还为第一个解决方案修复后发生的另一个错误添加了解决方案。请看MSDN上的例子,我在回答中也贴了一个链接。我想带有
typeof(B)
的serializer的定义不会让我们序列化a的进一步实现,是吗?使用类型数组作为构造函数的第三个参数,它可能会工作,请参见may answer.Nope。但你的问题听起来不一样。“我所要做的就是序列化一个B实例,它只是在A的定义中添加了一些属性。”您没有提到序列化另一个派生类。错误消息本身很有可能是错误的。并且已经超过7年没有被修复。我将第三个参数添加到XmlSerializer中,以指定可能的类型数组,这些类型也可能派生自A(除了B之外)。
new XmlSerializer(typeof(B), overrides);
...
XmlSerializer ser = new XmlSerializer(typeof(A));
ser.Serialize(new XmlTextWriter("test.xml", Encoding.Default), foo);
...         

[System.Xml.Serialization.XmlRoot("Root", Namespace = "DefaultNS")]
[System.Xml.Serialization.XmlInclude(typeof(B))]
public class A { public int a;}

[System.Xml.Serialization.XmlRoot(Namespace = "CustomNS")]
public class B : A { public int b;}
...
XmlSerializer ser = new XmlSerializer(typeof(A), overrides, new[] { typeof(B) }, new XmlRootAttribute("Root"), "defautlNS");
...

public class A { public int a;}
public class B : A { public int b;}