使用 XmlSerializer 时,可以在 xml 序列化中使用抽象类

本文关键字:序列化 抽象类 xml XmlSerializer 使用 | 更新日期: 2023-09-27 18:17:59

问题
当我将System.Xml.Serialization.XmlSerializer与用 System.Xml.Serialization 属性装饰的类一起使用时(例如 XmlRootXmlElement , ...我可以在某些类中创建类型作为抽象类的属性吗?

场景
我有这些课程:

[XmlRoot("autor")]
public class Author
{
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlArray("books")]
    [XmlArrayItem("book")]
    public List<Book> Livros { get; set; }
    [XmlElement("info")]
    public ExtraData ExtraData { get; set; }
}
public class Book
{
    [XmlElement("name")]
    public string Name { get; set; }
    [XmlElement("year")]
    public int Year { get; set; }
}
public abstract class ExtraData
{
}
public class ExtraDataTest : ExtraData
{
    [XmlElement("test")]
    public string Test { get; set; }
}

我尝试这个片段:

var author = new Author
{
    Name = "George R. R. Martin",
    Livros = new List<Book>
    {
        new Book { Name = "A Game of Thrones", Year = 1996 },
        new Book { Name = "The Hedge Knight", Year = 1998 },
    },
    // ExtraData = new ExtraDataTest { Test = "Some Info" }
    // See the comment below to know why this line was commented.
};
var serializer = new XmlSerializer(typeof(Author));
using(var ms = new MemoryStream())
using(var sw = new StreamWriter(ms))
using(var sr = new StreamReader(ms))
{
    var ns = new XmlSerializerNamespaces();
    ns.Add("","");
    serializer.Serialize(sw, author, ns);
    sw.Flush();
    ms.Position = 0;
    sr.ReadToEnd().Dump(); // Dump is a extended method of LinqPad
}

结果是:

<?xml version="1.0" encoding="utf-8"?>
<autor>
  <name>George R. R. Martin</name>
  <books>
    <book>
      <name>A Game of Thrones</name>
      <year>1996</year>
    </book>
    <book>
      <name>The Hedge Knight</name>
      <year>1998</year>
    </book>
  </books>
</autor>

问题
因此,如果我取消注释设置 ExtraData 属性的行,当我尝试序列化对象时会抛出一个异常:


System.ObjectDisposedException 无法访问已关闭的流。

所以这就是为什么我要问是否可能,如果是,如何?

使用 XmlSerializer 时,可以在 xml 序列化中使用抽象类

这是可能的。

我从您的代码中看到的唯一缺少的是在您的抽象类上使用 XmlInclude 属性来通知序列化程序它应该查找如下所示的派生类:

[XmlInclude(typeof(ExtraDataTest))]
public abstract class ExtraData
{
}