序列化將物件轉換為外部形式(如檔案儲存、跨程序通訊),逆過程為反序列化。BinaryFormatter 以高效率二進位格式處理,支援基本型別、陣列、日期時間、集合等複雜物件圖。
BinaryFormatter^ formatter = gcnew BinaryFormatter;
Stream^ file = File::Open("Sr01.ser", FileMode::Create);
formatter->Serialize(file, "Hello");
formatter->Serialize(file, intArray);
formatter->Serialize(file, floatArray);
formatter->Serialize(file, true);
formatter->Serialize(file, DateTime::Now);
formatter->Serialize(file, 1000);
formatter->Serialize(file, L'X');
formatter->Serialize(file, 1.23456F);
file->Close();
// 反序列化需按相同順序讀取並轉型
file = File::Open("Sr01.ser", FileMode::Open);
String^ s = static_cast(formatter->Deserialize(file));
array^ arr = static_cast^>(formatter->Deserialize(file));
// ...
序列化時物件會被「裝箱」,反序列化需對應「拆箱」轉型。
單一 Serialize 呼叫即可處理任意大小、複雜度的物件圖:
Hashtable^ dict = gcnew Hashtable(21000);
// 從檔案讀入 20000+ 字彙...
formatter->Serialize(file, dict); // 一次寫入完整字典
反序列化後可直接查詢,效能極佳。
同一序列化串流內多次序列化相同物件參考:
Employee^ emp1 = gcnew Employee();
Employee^ emp2 = gcnew Employee();
Employee^ emp3 = emp2; // 同一參考
array
關鍵發現:逐個序列化多個目標時,反序列化後參考關係**不會**自動恢復(emp2 != emp3,list[0] != emp1),但物件**內部**參考關係仍保持。若需保持圖結構,應將根物件(如包含所有參考的陣列或容器)一次序列化。
類別必須標記 [Serializable] 屬性,否則拋出 SerializationException。
預設序列化所有非靜態實例欄位。若類別包含靜態欄位(如計數器),反序列化不會呼叫建構函式,導致靜態狀態不一致。解決方案:實作 ISerializable:
GetObjectData(SerializationInfo^, StreamingContext):自訂序列化資料,透過 AddValue(name, value) 指定欄位MyClass(SerializationInfo^, StreamingContext):專供反序列化機制呼叫除 BinaryFormatter 外,可使用 SoapFormatter 產生 XML 基礎的 SOAP 格式,具高度模組化與擴展性。開發者亦可實作自訂格式化器。