【问题标题】:XML Serialization Derived Types using value of an Attribute使用属性值的 XML 序列化派生类型
【发布时间】:2016-03-14 18:06:37
【问题描述】:

我正在修改一组正在序列化的类,但我有一个找不到答案的问题。旧的类有一个非常大的类,称为 Control,它由 ControlType 属性进一步分类

enum ControlType
{
    ControlType1 = 0,
    ControlType2 = 1
}

public class Control
{
    [XmlAttribute("a")]
    public string a { get; set; }

    [XmlAttribute("b")]
    public string b { get; set; }

    [XmlAttribute("Type")]
    public ControlType Type {get; set;)
}

在上面的简化示例中,原始设计者没有将类分离为子类。我们真正想要的是

class baseControl
{
     [XmlAttribute("Type")]
     public ControlType Type {get; set;}
}

class Control1 : baseControl
{
    [XmlAttribute("a")]
    public string a { get; set; }
}

class Control2 : baseControl
{ 
    [XmlAttribute("b")]
    public string b { get; set; }
}

我们想分离出类,但我们希望原始 xml 兼容

在旧层次结构中,所有控件类型(由 ControlType 定义)都被序列化为

<Control Type="ControlType1" a="xxxx" />
<Control Type="ControlType2" b="xxxxx" />

如果我们使用新结构显然新结构看起来像

<Control1 Type="ControlType1" a="xxxx" />
<Control2 Type="ControlType2" b="xxxxx" />

但我们确实希望将所有新派生类序列化为“Control”,并且在反序列化时,我们希望根据 Attribute 的值将分配的类型更改为派生类型。

这可能吗?

【问题讨论】:

  • 您可以使用[XmlElement("Control")] 确保您的所有控件类都写为&lt;Control ... &gt;。我不确定是否可以使用XmlSerializer 确保它们都正确反序列化。

标签: c# xml serialization deserialization


【解决方案1】:

实现这种行为的唯一机会是在对应于环绕元素的类上实现IXmlSerializable,并提供自定义(反)序列化行为。

public class ControlContainer : IXmlSerializable
{
    // a single / array of / list of BaseControls
    public BaseControl Control { get; set; }

    // … any other properties

    // … implement IXmlSerializable here to have Control 
    // and any other properties (de)serialized
}

【讨论】:

  • 好的,这完全有道理,但我有一个问题。在大多数情况下,我想要标准序列化,我唯一需要做的就是读取类型并分配正确的派生类。如何实现 ReadXml() 并调用 Serializer 的基本实现,然后发挥我的作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2014-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多