如何序列化/反序列化具有公共根类的对象列表?

时间:2009-06-29 20:45:45

标签: c# xml inheritance xml-serialization

  

相关:How can I use polymorphism in XML Serialization?

我有一个我编写的类,用于在应用程序会话之间将用户的首选项序列化到磁盘。要读/写我正在使用XmlSerializer.Deserialize()和XmlSerializer.Serialize()。获取序列化的一个属性是不同应用程序组件的子设置列表。为了实现这一点,我有以下内容(该属性仅在序列化期间使用):

private readonly Dictionary<SettingType, SubSettings> subSettings;    

[XmlArray("SubSettings")]
[XmlArrayItem("SubSetting", Type=typeof(DictionaryEntry))]
public DictionaryEntry[] _SubSettings
{
    get
    {
        int i = 0;

        //Make an array of DictionaryEntries to return 
        DictionaryEntry[] result = new DictionaryEntry[subSettings.Count];

        foreach( KeyValuePair<SettingType, SubSettings> setting in subSettings ) {
            DictionaryEntry entry = new DictionaryEntry( setting.Key, setting.Value );
            result[i] = entry;
            i++;
        }

        return result;
    }
    set
    {
        subSettings.Clear();
        for( int i = 0; i < value.Length; i++ )
            subSettings.Add( (SettingType)value[i].Key, (SubSettings)value[i].Value );
    }
}

这一切都很好地为我服务,所有字典的值都是动态的SubSettings。问题是,现在我想让一些SubSettings对象成为不同的动态类型(CoolSubSettings:SubSettings)。显而易见的问题是,如果我这样做,我将无法进行通信,因为XML读取了每个SubSettings节点应该是什么动态类型,并且不会读取或写入其附加属性。

1 个答案:

答案 0 :(得分:2)

这是因为序列化程序不知道所有类型,你必须告诉他必须使用哪些类型。例如,您无法尝试以下方法:

struct DictEntry<T>
{
   public SettingType Key;
   public T Value;
}

// ...

[XmlArray("SubSettings")]
[XmlArrayItem("SubSetting", Type=typeof(DictEntry<SubSettings>))]
[XmlArrayItem("CoolSubSetting", Type=typeof(DictEntry<CoolSubSettings>))]
public object[] _SubSettings
{
    // ...

更新:针对您的问题的另一种解决方案:

struct DictEntry
{
    public SettingType Key;        
    [XmlElement("SubSettingValue", Type=typeof(SubSettings))]        
    [XmlElement("CoolSubSettingValue", Type=typeof(CoolSubSettings))]
    public object Value;
}

[XmlArray("SubSettings")]
public DictEntry[] _SubSettings
{
    // ...

我认为您了解主要的实施理念?顺便说一下,我不确定这种情况下的继承,我现在无法测试它。但是遇到麻烦你可以为SubSettings和CoolSubSettings创建基本的祖先。