使用 IXmlSerialization,如何序列化 T 属性

本文关键字:序列化 属性 IXmlSerialization 使用 | 更新日期: 2023-09-27 18:33:03

我的问题很简单。

假设我们有一个 Foo 类,并且有一个 T 属性。

public class Foo<T>
{
    public T Property { get; set; }
}

我想在其中实现IXmlSerializable,我的问题是我不知道模仿标准的XmlSerialization。我真的不知道如何像标准 XmlSerlalization 一样编写此属性。

更新:我这样做了,但它不起作用

public class Foo<T> : IFoo
    where T : IXmlSerializable
{
    public T Value { get; set; }
}
public class FooA : Foo<string> { }
public class FooB : Foo<int> { }
public class FooC : Foo<List<Double>> { }

当我序列化这些类(A、B 和 C)时。我想要这样的东西:

使用头等舱:

<FooA>
    <Value>StringDemo</Value>
</FooA>

使用二等:

<FooB>
    <Value>2</Value>
</FooB>

使用第三类:

<FooC>
    <Value>
        <ArrayOfDouble xsi:..>
            <Double>3.1416</Double>
            <Double>4.2</Double>
        </ArrayOfDouble>
    </Value>
</FooC>

像这样的东西是我想要的,我不想在所有这些中实现自定义 XmlSerializer,我的意思是标准序列化使用的默认值。

使用 IXmlSerialization,如何序列化 T 属性

你需要

Foo<T>和T(使用where T : IXmlSerializable .然后,Foo<T> 中的实现将负责编写带有类型信息的包装器元素(在 WriteXML 中)并在 T 上调用 WriteXml,并从类型信息(在 ReadXML 中)重新创建实例并在 T 上调用ReadXml

StringDouble等基本类型不是 IXmlSerializable ,因此如果您想支持它们,则不能where T : IXmlSerializable。您还可以提供 ReadXmlWriteXml 的默认实现。这是有效的,因为您需要在调用ReadXml之前创建一个Foo<T>,迫使您知道T

public class Foo<T> : IXmlSerializable {
    public T Value { get; set; }
    XmlSchema IXmlSerializable.GetSchema() {
        return GetSchema();
    }
    protected virtual XmlSchema GetSchema() {
        return null;
    }
    public virtual void ReadXml(XmlReader reader) {
        reader.ReadStartElement();
        var xmlSerializer = new XmlSerializer(typeof(T));
        Value = (T)xmlSerializer.Deserialize(reader);
        reader.ReadEndElement();
    }
    public virtual void WriteXml(XmlWriter writer) {
        var xmlSerializer = new XmlSerializer(typeof(T));
        xmlSerializer.Serialize(writer, Value);
    }
}