close
之前寫過一篇 如何用 C# 撰寫序列化(Serialize)與反序列化(Deserialize),最近正好又有專案用上,心想乾脆寫一個泛型的版本,讓以後所有專案都可以使用。
完整的程式碼如下:
- using System.IO;
- using System.Text;
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) 時的用法如下:
- TestClass myObject = new TestClass { ID = "test"; };
- // 將 myObject 物件序列化成 Xml 格式 (字串型態)
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.IPAddress 或 System.Net.NetworkInformation.PhysicalAddress 這些型別都會無法進行序列化,錯誤訊息如下:
System.Net.NetworkInformation.PhysicalAddress cannot be serialized because it does not have a parameterless constructor.
解決的方法有兩種:
- 修改類別屬性,改用 string 型別儲存資料。
- 繼承無法序列化的型別,並實做 ISerializable 介面自訂序列化方法。
全站熱搜