真的很棘手... XmlSerialization 不是多态的,因此您的 XML 通常会提供对象层次结构的扁平化版本。我看到了两种可能的实现。第一个将基本属性公开为另一个名称(请参阅“ConcreteChild”)。另一个实现 IXmlSerialization(请参阅“ConcreteChild2”),以便您可以编写自定义的属性嵌套。
// Base Class
[Serializable]
[XmlInclude(typeof(ConcreteChild))]
public class BaseChild
{
public BaseChild()
{
ChildName = "Base";
}
public String ChildName { get; set; }
}
// Exposing Parent Property
[Serializable]
public class ConcreteChild : BaseChild
{
public new String ChildName { get; set; }
public String BaseChildName {
get
{
return ((BaseChild) this).ChildName;
}
set
{
((BaseChild)this).ChildName = value;
}
}
}
// Writing Custung Serializable
[Serializable]
public class ConcreteChild2 : BaseChild, IXmlSerializable
{
public new String ChildName { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
}
public void WriteXml(XmlWriter writer)
{
writer.WriteStartElement("InherittedChild");
writer.WriteElementString("ConcreteChildName", ChildName);
writer.WriteEndElement();
// Since BaseChild does not implement IXmlSerializable
// we cannot use base.WriteXml(writer);
writer.WriteElementString("BaseChildName", ((BaseChild) this).ChildName);
}
}
[XmlInclude(typeof(ConcreteChild))]
[XmlInclude(typeof(ConcreteChild2))]
[Serializable]
public class MyClass
{
public BaseChild Left { get; set; }
[XmlElement("ConcreteChild2", typeof(ConcreteChild2))] // does not work without !!!
public BaseChild Right { get; set; }
}
结果:您可以在 MyClass 结构中看到两个序列化
<?xml version="1.0" encoding="utf-16"?>
<MyClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Left xsi:type="ConcreteChild">
<ChildName>Left</ChildName>
<BaseChildName>Base</BaseChildName>
</Left>
<ConcreteChild2>
<InherittedChild>
<ConcreteChildName>Right</ConcreteChildName>
</InherittedChild>
<BaseChildName>Base</BaseChildName>
</ConcreteChild2>
</MyClass>
序列化
var mc = new MyClass();
mc.Left = new ConcreteChild { ChildName = "Left"};
mc.Right = new ConcreteChild2 { ChildName = "Right" };
StringWriter textWriter = new StringWriter();
XmlSerializer xmlSerializer = new XmlSerializer(mc.GetType());
xmlSerializer.Serialize(textWriter, mc);
var s = textWriter.ToString();