簡體   English   中英

從基類序列化和反序列化派生類

[英]Serialize and DeSerialized derived classes from the base class

我試圖創建一個基類,可以從中繼承(將屬性添加到派生類),並利用基類的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;
    }
  }
}

對於派生類,我應該能夠做類似的事情

ApplicationParameters參數= ApplicationParmeters.Load(“ settings.xml”);

但是,在上述實現中,當我在基類中調用Load方法時,嘗試將ApplicationSettings強制轉換為ApplicationParameters類時,會發生編譯器錯誤。

有沒有辦法做到這一點?

嘗試用GetType()替換typeof(ApplicationSettings)。

使用這種機制,您還將告訴序列化程序ApplicationParameters是ApplicationSettings的子類。 您可以通過XmlInclude執行此操作

[XmlInclude(typeof(ApplicationParameters))]
class ApplicationSettings

后者是串行器的要求,因為否則它將不知道要實例化哪個類。

為什么使用XmlSerializer?

除非必須控制輸出XML的外觀,否則建議使用DataContractSerializer

例如在這里

使頂級類通用,以便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");

取決於您使用的方法。

您的ApplicationParameters類中的構造函數如何將ApplicationSettings作為參數並將共享屬性從一個復制到另一個呢? 然后將非共享屬性設置為null或默認值...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM