【问题标题】:How to deserialize derived class with other derived class as property如何以其他派生类作为属性反序列化派生类
【发布时间】:2019-09-20 09:26:04
【问题描述】:

我有 2 个项目。一个是 WPF 应用程序,第二个是我的“工具包”,其中包含预定义的 WPF 控件、XML 反序列化和一些基本配置类。

在我的工具包中,我有一个 ConfigurationBase 类:

public class ConfigurationBase : XmlDeserializeConfigSectionHandler
{
      public GuiConfigurationBase GuiConfiguration { get; set; }
}

这是GuiConfigurationBase

public class GuiConfigurationBase
{
    public int LogLineCount { get; set; }
}

我的工具包包含应用程序日志消息的预定义视图。所以我的LogViewModel 构造函数需要一个ConfigurationBase,它应该包含GuiConfigurationLogLineCount 属性。

这是因为我不想在每个应用程序的应用程序日志中实现。

然后我有一个 WPF 项目。它包含一个派生自ConfigurationBase 的类Config。它使用其他一些不重要的道具进行了扩展。

我还需要扩展GuiConfigurationBase,所以我有一个名为GuiConfiguration 的类,它派生自GuiConfigurationBase

public class Config : ConfigurationBase
{
    public string AppName { get; set; }
}

public class GuiConfiguration : GuiConfigurationBase
{
    public int TextSize { get; set; }
}

我还使用 XmlSerializer 来反序列化我的 XML 文件。我需要填写我的两个派生类。

请问我该如何实现?

我尝试了一些基类的抽象,但没有成功。

感谢您的任何建议。

【问题讨论】:

  • 错字警告:它的拼写是 to derived / derived - 不是“to derrive / derived” - 一个“r”就足够了
  • 只要引用的类都是可序列化的,你应该能够反序列化。

标签: c# xml inheritance deserialization abstract


【解决方案1】:

我找到了解决方案。 必须使用XmlAttributeOverrides

因为我有两个项目,我不得不使用反射来检索派生自GuiConfigurationBase 的类。 (我对我的工具包项目引用的项目一无所知)

然后为每个类添加新的XmlElementAttribute(在我的情况下使用Linq First() 方法就足够了) - 这应该与XmlIncludeAttribute(Type) 相同

最后为ConfigurationBase类的属性GuiConfiguration添加XmlAttributeOverrides

这是我的反序列化方法:

 public T Deserialize<T>(string input) where T : class
    {
        //Init attrbibutee overrides
        XmlAttributeOverrides attrOverrides = new XmlAttributeOverrides();
        XmlAttributes attrs = new XmlAttributes();

        //Load all types which derive from GuiConfiguration base
        var guiConfTypes = (from lAssembly in AppDomain.CurrentDomain.GetAssemblies()
                            from lType in lAssembly.GetTypes()
                            where typeof(GuiConfigurationBase).IsAssignableFrom(lType) && lType != typeof(GuiConfigurationBase)
                            select lType).ToArray();


        //All classes which derive from GuiConfigurationBase
        foreach (var guiConf in guiConfTypes)
        {
            XmlElementAttribute attr = new XmlElementAttribute
            {
                ElementName = guiConf.Name,
                Type = guiConf
            };

            attrs.XmlElements.Add(attr);
        }

        //Add Attribute overrides for ConfigurationBase class's property GuiConfiguration
        attrOverrides.Add(typeof(ConfigurationBase), nameof(ConfigurationBase.GuiConfiguration), attrs);

        XmlSerializer ser = new XmlSerializer(typeof(T), attrOverrides);

        using (StringReader sr = new StringReader(input))
        {
            return (T)ser.Deserialize(sr);
        }
    }

我希望它会帮助别人:-)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-05
    • 1970-01-01
    相关资源
    最近更新 更多