在基类中实现IXmlSerializable时如何恢复到"默认"XML序列化?

Tim*_*mel 7 c# ixmlserializable

我正在尝试序列化一个继承自实现IXmlSerializable的基类的类.

名为PropertyBag的基类是一个允许动态属性的类(Marc Gravell的学分).

我实现了IXmlSerializable,以便将动态属性(存储在Dictionary中)写为普通的xml元素.

例如,当序列化具有公共属性(非动态)名称和动态属性Age的类时,我希望它生成以下XML:

<Person>
  <Name>Tim</Name>
  <DynamicProperties>
    <Country>
      <string>USA</string>
    </Country>
  </DynamicProperties>
<Person>
Run Code Online (Sandbox Code Playgroud)

我可以让部分在基础PropertyBag类中使用WriteXml的以下实现:

public void WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteStartElement("DynamicProperties");

        // serialize every dynamic property and add it to the parent writer
        foreach (KeyValuePair<string, object> kvp in properties)
        {
            writer.WriteStartElement(kvp.Key);

            StringBuilder itemXml = new StringBuilder();
            using (XmlWriter itemWriter = XmlWriter.Create(itemXml))
            {
                // serialize the item
                XmlSerializer xmlSer = new XmlSerializer(kvp.Value.GetType());
                xmlSer.Serialize(itemWriter, kvp.Value);                    

                // read in the serialized xml
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(itemXml.ToString());

                // write to modified content to the parent writer
                writer.WriteRaw(doc.DocumentElement.OuterXml);
            }

            writer.WriteEndElement();
        }

        writer.WriteEndElement();
    }
Run Code Online (Sandbox Code Playgroud)

但是,在序列化Person类时,它不再序列化正常(非动态)属性,除非我在Person中覆盖WriteXml方法(我不想这样做).有没有办法在基类中我可以自动添加静态属性?我知道我可以使用反射手动执行此操作,但我想知道.Net Framework中是否有一些内置功能?

Tim*_*mel 1

Marc,您关于将 FixProperties 放入单独集合中的答案让我想到,我应该创建该类型的属性,而不是从 PropertyBag 继承。

因此,我创建了一个 PropertyBagWrapper 类,我的 Person 类继承自该类,并且它可以工作。

[Serializable]
[TypeDescriptionProvider(typeof(PropertyBagDescriptionProvider))]    
public abstract class PropertyBagWrapper
{
    [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]    
    public PropertyBag DynamicProperties { get; set; }

    public object this[string name]
    {
        get { return DynamicProperties[name]; }
        set { DynamicProperties[name] = value; }
    }
    protected PropertyBagWrapper()
    {
        DynamicProperties = new PropertyBag(this.GetType());
    }
}

[Serializable]    
public class Person : PropertyBagWrapper
{
    [Browsable(true)]
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我不会重复 PropertyBag 和 ICustomTypeDescriptor 实现所需的自定义类的所有代码,您可以在此处找到。

我确实将 TypeDescriptionProvider 属性从 PropertyBag 类移至 PropertyBagWrapper 类。

PropertyBag 类仍然具有与问题中发布的 WriteXml() 方法相同的实现。