2010-04-25

隨筆:在 Visual Studio 中,使用 Serializable 儲存物件

既然現在 IDE / Framework 都把加速開發當作主要目標,Coder 再混也應該要學一學這些把戲 >///<


以往用 C/CPP 都可以把不含指標的 struct / class 直接 binary read/write,但在 Java / Visual Studio 裡,這樣的流程被稍微擴充,改以 Serialize / Deserialize 作為媒介 。簡單的說,Serialize 就是把一個物件(物件裡可以有指向其他物件的參考),弄成一個 Byte 陣列,可以拿去做其他壞事(傳到別的電腦上,或者存到硬碟裡);Deserialize 就是把這個 Byte 陣列弄回原本的物件,其中所有的變數都完全相同。 我是沒什麼興趣去查 Serialize / Deserialize 的使用限制在哪邊啦,不過碰到有交互參照繞圈圈,或者是變數含有資源(DB / File resources / Socket)的狀況,就算會爆炸也不意外啦。

使用 C# 時,需加上
using System.Runtime.Serialization ;
using System.Runtime.Serialization.Formatters.Binary ;

並在需要 Serialize / Deserialize 的 class 宣告前加上 [Serializable()]
在物件內,Serialize 時要忽略的變數前加上 [NonSerialized()]

儲存時參考程式碼:
IFormatter f = new BinaryFormatter();
Stream s = new FileStream(FILENAME, FileMode.Create, FileAccess.Write, FileShare.None);
f.Serialize(s, INSTANCENAME);
s.Close();

提取時參考程式碼:
IFormatter f = new BinaryFormatter();
Stream s = new FileStream(FILENAME, FileMode.Open, FileAccess.Read, FileShare.Read);
INSTANCENAME = (CLASSNAME) formatter.Deserialize(s);
s.Close();

註:詳細內容請參照 msdn : SerializableAtribute,欲求不滿再參考 ISerializable

補充,如果是 Class A 裡持有 Class B 變數的話,必須宣告 Class A/B 均為 Serializable(),才能將 Class A Serialize,否則會在 Runtime 出錯;或者可以將 Class B 設為 NonSerialized。另外,Serializable() 不會被繼承,因此要使用的物件需明確宣告。

沒有留言: