从基类序列化和DeSerialize派生类

时间:2010-10-18 12:56:43

标签: c# xml-serialization .net-2.0

我正在尝试创建一个基类,我可以从中继承它(向派生类添加属性)并使用基类中的Load和Save方法。我发现自己一遍又一遍地写着加载和保存,我想对它应用一些DRY ......

namespace Common

{
  using System;
  using System.IO;
  using System.Xml.Serialization;

  public abstract class ApplicationSettings
  {
    protected ApplicationSettings()
    {
    }

    public static ApplicationSettings Load(string fileName)
    {
      if (!File.Exists(fileName))
      {
        return null;
      }

      XmlSerializer serializer = new XmlSerializer(typeof(ApplicationSettings));

      using (StreamReader reader = new StreamReader(fileName))
      {
        ApplicationSettings param = (ApplicationSettings)serializer.Deserialize(reader);
        reader.Close();
        return param;
      }
    }

    public void Save(string fileName)
    {
      XmlSerializer serializer = new XmlSerializer(typeof(ApplicationSettings));
      using (StreamWriter writer = new StreamWriter(fileName))
      {
        serializer.Serialize(writer, this);
        writer.Close();
      }
    }
  }
}

鉴于这个抽象类,我想要派生一个类,如:

namespace Common
{
  using System;

  public class ApplicationParameters : ApplicationSettings
  {
    public ApplicationParameters()
    {
    }
    public string AuthorizationCode
    {
      get;
      set;
    }
    public string ReferenceNumber
    {
      get;
      set;
    }
  }
}

对于Derived类,我应该可以执行类似

的操作
  

ApplicationParameters参数=   ApplicationParmeters.Load( “settings.xml中”);

但是,在上面的实现中,当我在基类中调用Load方法时尝试将ApplicationSettings强制转换为ApplicationParameters类时,会发生编译器错误。

有办法做到这一点吗?

4 个答案:

答案 0 :(得分:3)

尝试使用GetType()替换typeof(ApplicationSettings)。

使用此机制,您还将告诉序列化程序ApplicationParameters是ApplicationSettings的子类。您可以通过XmlInclude

执行此操作
[XmlInclude(typeof(ApplicationParameters))]
class ApplicationSettings

后者是序列化程序的要求,否则它将无法知道要实例化的类。

答案 1 :(得分:2)

为什么使用XmlSerializer?

除非您必须控制输出XML的外观,否则建议使用DataContractSerializer

请参阅here,例如

答案 2 :(得分:1)

使顶级类具有通用性,以便Save / Load方法可以支持多种类型:

public abstract class ApplicationSettings<T>
{
    public static T Load(string xml){ // Implementation }

    public static void Save (T obj) { // Implementation }
}

public class ApplicationParameters : ApplicationSettings<ApplicationParameters>
{
}

或者你可以让静态方法本身通用:

public abstract class ApplicationSettings
{
    public static T Load<T>(string xml){ // implementation }

    public static void Save<T>(T obj){ // implementation }
}

现在您将注意到抽象父类的Save / Load方法是强类型的,因此以下行将按预期工作:

ApplicationParameters parameters = ApplicationParameters.Load("settings.xml");

ApplicationParameters parameters =
    ApplicationSettings.Load<ApplicationParameters>("settings.xml");

取决于您使用的方法。

答案 3 :(得分:0)

ApplicationParameters类中的构造函数如何将ApplicationSettings作为参数并将共享属性从一个复制到另一个?然后只需将not shared属性设置为null或默认值...