共用方式為


序列化

備註

此內容經Pearson Education, Inc.授權從架構設計指導方針:可重複使用 .NET 程式庫的慣例、習慣用語與範式 (第2版)轉載。 該版於2008年出版,該書自那以後已於 第三版全面修訂。 此頁面的某些資訊可能已過期。

串行化是將物件轉換成可輕易保存或傳輸的格式的程式。 例如,您可以串行化物件、使用 HTTP 透過因特網傳輸物件,並在目的地電腦上還原串行化它。

.NET Framework 提供三種針對各種串行化案例優化的主要串行化技術。 下表列出這些技術和與這些技術相關的主要架構類型。

技術名稱 主要類型 案例
數據合約串行化 DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
一般持續性
Web 服務
JSON(JavaScript物件標記法)
XML 串行化 XmlSerializer XML 格式,對 XML 結構具有完整控制權
執行時間串行化 (二進位和 SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
.NET 遠端處理

✔️ 當您設計新類型時,請考慮串行化。

選擇要支持的正確串行化技術

✔️ 如果型別的實例可能需要保存或使用於 Web 服務中,請考慮支援數據合約串行化。

✔️ 如果您需要對在類型序列化時產生的 XML 格式有更多控制,請考慮支援 XML 串行化,或者除了數據合約序列化外同時支援它。

在某些互作性案例中,您可能需要使用數據合約串行化不支援的 XML 建構,例如產生 XML 屬性。

✔️ 如果類型的實例需要跨越 .NET 遠端界限,請考慮支援運行時間串行化。

❌ 請避免只基於一般持續性原因支援運行時間串行化或 XML 串行化。 請改用資料契約序列化。

支援數據合約串行化

型別可以透過將 DataContractAttribute 套用至型別以及將 DataMemberAttribute 套用至型別的成員(欄位和屬性),以支援資料合約序列化。

✔️ 如果您的類型可以用於部分信任環境,請考慮將其數據成員設為公用。

在完全信任中,資料合約序列化器可以序列化和反序列化非公用類型和成員,但在部分信任中只有公用成員可以被序列化和反序列化。

請在所有具有 DataMemberAttribute 的屬性上實作 getter 和 setter。 數據合約串行化程式需要 getter 和 setter,才能將類型視為可串行化。 在 .NET Framework 3.5 SP1 中,某些集合屬性可以是唯讀。如果類型不會用於部分信任,則屬性存取子中有一或兩個可以設定為非公開。

✔️ 請考慮使用串行化回呼進行還原串行化實例的初始化。

還原串行化物件時,不會呼叫建構函式。 (規則有例外。在還原串行化期間,會呼叫標示 CollectionDataContractAttribute 為 的集合建構函式。因此,在正常建構期間執行的任何邏輯都必須實作為其中一個串行化回呼。

OnDeserializedAttribute 是最常用的回呼屬性。 系列中的其他屬性是 OnDeserializingAttributeOnSerializingAttributeOnSerializedAttribute。 它們可用來分別標記回呼,在反序列化之前執行、序列化之前執行,以及序列化之後執行。

✔️ 請考慮使用 KnownTypeAttribute 來指出還原串行化複雜物件圖形時應該使用的具體型別。

✔️ 建立或變更可串行化類型時,請考慮回溯和向前相容性。

請記住,您類型未來版本的串行化數據流可以還原串行化為目前的類型版本,反之亦然。

請確定您了解資料成員,即使是私有和內部,也無法在資料型別的未來版本中變更其名稱、類型,或甚至是其順序,除非特別注意,透過資料合約屬性的明確參數來保留合約。

對可串行化類型進行變更時,測試串行化的相容性。 將新版本反序列化為舊版本,反之亦然。

✔️ 請考慮實作 IExtensibleDataObject 以允許在不同版本的型別間進行往返處理。

介面可讓串行化程序確保不會在來回行程期間遺失任何數據。 屬性 IExtensibleDataObject.ExtensionData 可用來儲存目前版本未知之類型未來版本的任何數據,因此無法將其儲存在其數據成員中。 當當前版本序列化並反序列化為未來版本時,序列化的資料流中將包含額外的數據。

支援 XML 串行化

數據合約串行化是 .NET Framework 中的主要(預設)串行化技術,但有數據合約串行化不支援的串行化案例。 例如,它不會讓您完全控制串行化程式所產生或取用之 XML 的形狀。 如果需要這類精細控制,則必須使用 XML 串行化,而且您必須設計類型以支援此串行化技術。

❌ 請避免特別針對 XML 串行化設計類型,除非您有非常強大的理由來控制產生的 XML 形狀。 此串行化技術已由上一節所討論的數據合約串行化取代。

✔️ 如果您想要對串行化 XML 的形狀擁有比套用 XML 串行化屬性所提供的更多控制權,請考慮實 IXmlSerializable 作 介面。 介面的ReadXmlWriteXml這兩種方法可讓您完全控制序列化的 XML 流。 您也可以套用 XmlSchemaProviderAttribute來控制為型別產生的 XML 架構。

支援運行時間串行化

運行時間串行化是 .NET 遠端處理所使用的技術。 如果您認為型別會使用 .NET 遠端傳輸,您必須確定它們支援執行時序列化。

您可以套用 SerializableAttribute來提供運行時間串行化的基本支援,而且更進階的案例牽涉到實作簡單的運行時間可串行化模式(實 ISerializable 作並提供串行化建構函式)。

✔️ 如果您的類型將搭配 .NET 遠端處理使用,請考慮支援運行時間串行化。 例如,System.AddIn 命名空間使用 .NET 遠端處理,因此 System.AddIn 附加元件之間交換的所有類型都需要支援執行階段序列化。

✔️ 如果您想要完全控制串行化程式,請考慮實作運行時間可串行化模式。 例如,如果您想要將數據在序列化或反序列化時進行轉換。

模式非常簡單。 您只需要實作ISerializable介面,並提供在反序列化物件時所使用的特殊建構函式。

✔️ DO 使序列化建構函式受到保護,並提供兩個參數,這些參數的型別和命名必須與此處範例所示完全一致。

[Serializable]
public class Person : ISerializable
{
    protected Person(SerializationInfo info, StreamingContext context)
    {
        // ...
    }
}

✔️ 應該明確實作 ISerializable 成員。

✔️ 請將連結需求套用至 ISerializable.GetObjectData 實作。 這可確保只有完全信任的核心和執行階段序列化器可以存取成員。

© 2005年、2009年Microsoft公司部分。 保留所有權利。

經 Pearson Education, Inc. 許可重新刊登自 Krzysztof Cwalina 和 Brad Abrams 所著的 架構設計指導方針: 可重複使用的 .NET 程式庫慣例、慣用語和模式,第 2 版,2008 年 10 月 22 日由 Addison-Wesley Professional 發行,作為 Microsoft Windows 開發系列的一部分。

另請參閱