我有一个类层次结构,我想使用XmlSerializer
该类及其相关属性对其进行序列化。有一个基本抽象类,然后是相当多的派生类(在下面的代码中,我将派生类的数量减少到五个,但实际代码中还有更多)。这些类形成一个层次结构,并且经常包含对层次结构中类实例的引用。
public abstract class BaseType
{
// Only classes in my assembly can derive from this class
internal BaseType() { }
}
public sealed class TType : BaseType
{
[XmlText]
public string Name;
}
public sealed class PType : BaseType
{
[XmlElement("t", typeof(TType)]
[XmlElement("p", typeof(PType)]
[XmlElement("a", typeof(AType)]
[XmlElement("s", typeof(SType)]
[XmlElement("u", typeof(UType)]
public BaseType Child;
}
public sealed class SType : BaseType
{
[XmlElement("t", typeof(TType)]
[XmlElement("p", typeof(PType)]
[XmlElement("s", typeof(SType)]
[XmlElement("a", typeof(AType)]
[XmlElement("u", typeof(UType)]
public BaseType [] Items;
public string [] ItemNames;
}
public sealed class AType : BaseType
{
[XmlElement("t", typeof(TType)]
[XmlElement("p", typeof(PType)]
[XmlElement("s", typeof(SType)]
[XmlElement("a", typeof(AType)]
[XmlElement("u", typeof(UType)]
public BaseType Item;
public int Length;
}
public sealed class UType : BaseType
{
[XmlElement("t", typeof(TType)]
[XmlElement("p", typeof(PType)]
[XmlElement("s", typeof(SType)]
[XmlElement("a", typeof(AType)]
[XmlElement("u", typeof(UType)]
public BaseType [] Alts;
public string [] AltNames;
}
最后,一个容器将它们全部容纳并喂给XmlSerializer
:
[XmlRoot("items")]
public class ItemCollection
{
[XmlElement("t", typeof(TType)]
[XmlElement("p", typeof(PType)]
[XmlElement("s", typeof(SType)]
[XmlElement("a", typeof(AType)]
[XmlElement("u", typeof(UType)]
public BaseType [] Items;
}
如您所见,我的代码中有很多重复。XmlElement
在某些时候,可能会引入一个新的派生类,并且必须使用新属性重新访问所有使用 BaseType 引用的地方。这既乏味又容易出错。我想表达一个事实,BaseType
如果元素名称为“t”,则 a 可以反序列化为 TType,但如果元素名称为“p”等,则为 PType,恰好一次。
我知道,XmlIncludeAttribute
但它引入xsi:type
了“金主”不满意的属性。有什么方法可以分解出 XML 元素名称和 CLR 类型之间的映射知识?
解决方案可以做出的一个假设是,定义BaseType
. 这意味着我们不必考虑将新类添加到组合中的外部程序集。