close

之前寫過一篇 如何用 C# 撰寫序列化(Serialize)與反序列化(Deserialize),最近正好又有專案用上,心想乾脆寫一個泛型的版本,讓以後所有專案都可以使用。

完整的程式碼如下:

  1. using System.IO;   
  2. using System.Text;   
using System.Xml.Serialization;   
using System.Xml;   
  public static class SiteHelper   {    public static string Serialize(object o)    {    XmlSerializer ser = new XmlSerializer(o.GetType());    StringBuilder sb = new StringBuilder();    StringWriter writer = new StringWriter(sb);    ser.Serialize(writer, o);    return sb.ToString();    }      public static T Deserialize (string s)    {    XmlDocument xdoc = new XmlDocument();      try   {    xdoc.LoadXml(s);    XmlNodeReader reader = new XmlNodeReader(xdoc.DocumentElement);    XmlSerializer ser = new XmlSerializer(typeof(T));    object obj = ser.Deserialize(reader);      return (T)obj;    }    catch   {    return default(T);    }    }   }  
using System.IO;
using System.Text;
using System.Xml.Serialization;
using System.Xml;

public static class SiteHelper
{
  public static string Serialize(object o)
  {
    XmlSerializer ser = new XmlSerializer(o.GetType());
    StringBuilder sb = new StringBuilder();
    StringWriter writer = new StringWriter(sb);
    ser.Serialize(writer, o);
    return sb.ToString();
  }

  public static T Deserialize (string s)
  {
    XmlDocument xdoc = new XmlDocument();

    try
    {
      xdoc.LoadXml(s);
      XmlNodeReader reader = new XmlNodeReader(xdoc.DocumentElement);
      XmlSerializer ser = new XmlSerializer(typeof(T));
      object obj = ser.Deserialize(reader);

      return (T)obj;
    }
    catch
    {
      return default(T);
    }
  }
}

序列化(Serialize) 與 反序列化(Deserialize) 時的用法如下:

  1. TestClass myObject = new TestClass { ID = "test"; };   
  2.   
  3. // 將 myObject 物件序列化成 Xml 格式 (字串型態)   
string s = SiteHelper.Serialize(myObject);   
  // 將 s 字串反序列化成 TestClass 型別的物件   
TestClass o = SiteHelper.Deserialize (s);  
TestClass myObject = new TestClass { ID = "test"; };

// 將 myObject 物件序列化成 Xml 格式 (字串型態)
string s = SiteHelper.Serialize(myObject);

// 將 s 字串反序列化成 TestClass 型別的物件
TestClass o = SiteHelper.Deserialize (s);

---

在序列化的過程中其實並非所有物件都可以序列化,只要序列化失敗就會引發 Exception,但我的程式在寫「反序列化」已經做了 try/catch,所以只要反序列化失敗會直接回傳該型別的預設值 ( 只要是參考型別就會回傳 null ),在這裡我利用 C# 中的 default 關鍵字來取得應用泛型時物件的預設值。

像我在測試的過程中發現 System.Net.IPAddressSystem.Net.NetworkInformation.PhysicalAddress 這些型別都會無法進行序列化,錯誤訊息如下:

System.Net.NetworkInformation.PhysicalAddress cannot be serialized because it does not have a parameterless constructor.

解決的方法有兩種:

  1. 修改類別屬性,改用 string 型別儲存資料。
  2. 繼承無法序列化的型別,並實做 ISerializable 介面自訂序列化方法。
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 AndrewHsiao 的頭像
    AndrewHsiao

    Andrew的部落格

    AndrewHsiao 發表在 痞客邦 留言(0) 人氣()