如何在反序列化时覆盖默认集合

3

我有一个类代表一些设置:

public class Settings
{
   public Settings()
   {
       InnerSettings = new List<InnerSettings>();
       //this is the settings i want to have by default
       InnerSettings.Add(new InnerSettings());
   }
   [XmlArray]
   public List<InnerSettings> InnerSettings {get; set;}
}

现在,当我反序列化这个对象时,XML中的InnerSettings被添加到默认Settings()构造函数创建的项的顶部List上。有没有一种简单的方法告诉反序列化程序,我想要覆盖集合,删除默认项?

你想反序列化除了InnerSettings之外的所有内容吗? - Yuval Itzchakov
@YuvalItzchakov жҲ‘жғіжҠҠдёҖеҲҮеҸҚеәҸеҲ—еҢ–пјҢдҪҶжҲ‘дёҚеёҢжңӣеңЁеҸҚеәҸеҲ—еҢ–еҜ№иұЎдёӯеҮәзҺ°й»ҳи®Өзҡ„Settings()жһ„йҖ еҮҪж•°ж·»еҠ зҡ„InnerSettingsпјҲйҷӨйқһе®ғ们д№ҹд»ҘXMLж јејҸеӯҳеңЁпјүгҖӮ - Nikita B
创建一个带有默认设置的基类。然后让你的设置类继承这个基类。 - jdweng
1个回答

2

XML序列化程序不支持任何回调函数,如果从XmlSerializer类派生,您可以重写一些方法。下面是一些(肮脏的)解决方法:

1)更改默认构造函数(XmlSerializer将调用该函数),不包括默认项。添加第二个构造函数和一个虚假参数,并公开一个工厂方法:

public class Settings {
   private Settings() {
       // Called by XmlDeserializer
   }

   private Settings(int dummy) {
       // Called by factory method
       InnerSettings = new List<InnerSettings> { new InnderSettings(); }
   }

   public static Settings Create() {
       return new Settings(0);
   }
}

2)在对象反序列化后删除项目。 为此创建您自己的XmlSerializer

public class SettingsXmlSerializer : XmlSerializer {
    protected override object Deserialize(XmlSerializationReader reader) {
        var settings = (Settings)base.Deserialize(reader);
        settings.InnerSettings.RemoveAt(0);

        return settings;
    }
}

3) 这应该是正确的方法,但对于复杂类型来说并不容易:需要实现IXmlSerializable接口,这是一个繁琐的工作...


1
谢谢。最终我在Settings类上创建了一个静态属性来保存默认预设,并从默认构造函数中删除了这个逻辑。不过我想知道为什么序列化会以这种方式工作。它为什么要将项添加到现有集合中,而不是重新创建它?这种行为的用例是什么? - Nikita B
1
因为XML序列化只是调用默认构造函数来创建一个新对象,然后使用来自XML文件的数据填充该实例。这使得初始化代码更加“简单”,但如果您习惯于其他序列化机制,则可能会产生反直觉的感觉。 - Adriano Repetti
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Nikita B
是的,这并不是真实的!但它有一个优点,可以“模拟”您的对象在代码中的使用方式,然后所有机制仍然按预期工作(例如,如果您将事件处理程序附加到每个添加的项)。 - Adriano Repetti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接