C#Xml-使用IXmlSerializable对派生类进行序列化

我有一个与XML序列化兼容的基类和一个实现IXmlSerializable的派生类。

在此示例中,基类确实实现了IXmlSerializable:

using System.Diagnostics; using System.Text; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; namespace XmlSerializationDerived { public class Foo { public int fooProp; public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { fooProp = int.Parse (reader.ReadElementString ("fooProp")); } public void WriteXml(XmlWriter writer) { writer.WriteElementString ("fooProp", fooProp.ToString ()); } } public class Bar : Foo, IXmlSerializable { public new void ReadXml(XmlReader reader) { base.ReadXml (reader); } public new void WriteXml(XmlWriter writer) { base.WriteXml (writer); } static void Main(string[] args) { StringBuilder sb = new StringBuilder (); XmlWriter writer = XmlWriter.Create (sb); Bar bar = new Bar (); bar.fooProp = 42; XmlSerializer serializer = new XmlSerializer (typeof (Bar)); serializer.Serialize (writer, bar); Debug.WriteLine (sb.ToString ()); } } } 

这会产生以下输出:

 42 

但是,我想使用一个实现IXmlSerializable的基类。 这可以防止使用base.Read/WriteXml 。 结果将是:

  

有没有办法仍能得到理想的结果?

“这可以防止使用base.Read/WriteXml。”

通常,如果基类实现了IXmlSerializable ,您可以将其设置为virtual方法,以便使用具体版本。 通常,您还使用显式实现(而不是公共属性) – 可能使用一些protected virtual方法来实现详细信息(尽管跟踪读者/作者在不同类中的位置将是一场噩梦)。

AFAIK,在添加派生位时,无法重用XmlSerializer来写入基本位。 IXmlSerializable是全有或全无。

改善mtlung的答案,为什么不使用XmlSerializer? 您可以使用属性调整您的类,以便可以按照您希望的方式对其进行序列化,并且这很简单。

 using System.Xml.Serialization; ... [XmlRoot("someclass")] public class SomeClass { [XmlAttribute("p01")] public int MyProperty01 { get { ... } } [XmlArray("sometypes")] public SomeType[] MyProperty02 { get { ... } } [XmlText] public int MyProperty03 { get { ... } } public SomeClass() { } } 

然后,序列化和反序列化将非常简单:

 void Save(SomeClass obj) { XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); using (FileStream fs = new FileStream("c:\\test.xml", ...)) { xs.Serialize(fs, obj); } } void Load(out SomeClass obj) { XmlSerializer xs = new XmlSerializer(typeof(SomeClass)); using (FileStream fs = new FileStream("c:\\test.xml", ...)) { obj = xs.Deserialize(fs); } } 

结果XML将是这样的:

     # value of "MyProperty03" as text #  

这种方法在“POCO”类中效果更好,而且简单干净。 您甚至不必使用属性,它们可以帮助您自定义序列化。

为什么不在您的读/写函数中简单地使用XmlSerializer?

 XmlSerializer s = new XmlSerializer(typeof(Foo)); s.Serialize(writer, base);