【问题标题】:How do you serialize/deserialize a list of objects with a common root class?如何序列化/反序列化具有公共根类的对象列表?
【发布时间】:2009-06-30 23:38:49
【问题描述】:

相关: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 节点应该是什么动态类型,并且不会读取或写入其附加属性。

【问题讨论】:

    标签: c# xml inheritance xml-serialization


    【解决方案1】:

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

    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 创建基本祖先。

    【讨论】:

    • 但是底层的字典呢?如果我按照您的建议进行操作,它会知道何时进入 subSettings 字段的条目,静态键入为 SubSettings,它应该被序列化为 CoolSubSettings 吗?
    • 底层逻辑由你决定。只要您提供正确的(并被序列化程序识别)类型,一切都必须正常工作。例如,在获取属性中,您必须根据您的字典值类型使用正确的 DictEntry 类型填充结果数组。
    • 我想我明白你在说什么,我会尝试一下。在继承方面,CoolSubSettings 继承自 SubSettings,所以这不是问题。
    • 做到了,非常感谢。我能够根据您的建议解决其余的问题。
    猜你喜欢
    • 2023-04-03
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-17
    • 1970-01-01
    • 2012-11-22
    • 2011-02-27
    相关资源
    最近更新 更多