選擇序列化程式
沒有直接替代 BinaryFormatter 的序列化程式,但有幾個推薦的序列化程式可以用於序列化 .NET 類型。 無論您選擇哪個序列化程式,都需要進行更改,才能與新的序列化程式整合。 在這些移轉期間,請務必考慮讓新的序列化器強制處理現有的型別,盡量少做變更,或重構型別以啟用與所選序列化器相符的慣用序列化方式。 一旦選擇了序列化程式後,應該研究其文件以了解最佳做法。
如果二進位串行化格式並非必要,您可以考慮使用 JSON 或 XML 串行化格式。 這些序列化程式已包含在 .NET 中並且得到官方支援。
- 使用 System.Text.Json 的 JSON
- 使用
System.Runtime.Serialization.DataContractSerializer
的 XML
如果您的案例而言,壓縮二進位表示法很重要,建議使用下列串行化格式和開放原始碼串行化程式:
您是否能夠控制變更串行化類型的 API 圖形,將會影響串行化的方向和方法。 移轉到這些序列化程式可能會更加直接,這取決於您是否能夠使用新屬性標註類型、新增建構函式、將類型/成員設為公共,並將欄位改為屬性。 如果沒有這種能力,使用現代序列化程式可能需要實作自訂轉換器或解析器。
功能 | BinaryFormatter | System.Text.Json | DataContractSerializer | C# 用 MessagePack | protobuf-net |
---|---|---|---|---|---|
Serialization format | 二進位 (NRBF) | JSON | XML | 二進位 (MessagePack) | 二進位 (Protocol Buffers) |
緊湊表示法 | ✔️ | ❌ | ❌ | ✔️ | ✔️ |
易於閱讀 | ❌️ | ✔️ | ✔️ | ❌️ | ❌️ |
效能 | ❌️ | ✔️ | ❌ | ✔️ | ✔️ |
[Serializable] 屬性支援 |
✔️ | ❌ | ✔️ | ❌ | ❌ |
序列化公共類型 | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
序列化非公共類型 | ✔️ | ✔️ | ✔️ | ✔️ (需要解析器) | ✔️ |
序列化欄位 | ✔️ | ✔️ (選擇性) | ✔️ | ✔️ (需要屬性) | ✔️ (需要屬性) |
序列化非公共欄位 | ✔️ | ✔️ (需要解析器) | ✔️ | ✔️ (需要解析器) | ✔️ (需要屬性) |
序列化屬性 | ✔️* | ✔️ | ✔️ | ✔️ (需要屬性) | ✔️ (需要屬性) |
還原序列化唯讀成員 | ✔️ | ✔️ (需要屬性) | ✔️ | ✔️ | ✔️ (需要無參數建構函式) |
多型類型階層 | ✔️ | ✔️ (需要屬性) | ✔️ | ✔️ (需要屬性) | ✔️ (需要屬性) |
AOT 支援 | ❌️ | ✔️ | ❌ | ✔️ | ❌ (已規劃) |
使用 System.Text.Json 的 JSON
System.Text.Json
庫是一個現代序列化程式,強調安全性、高效能和低記憶體配置,用於 JavaScript 物件表示法 (JSON) 格式。 JSON 易於閱讀,並且具有廣泛的跨平台支援。 雖然文字格式不像二進位格式那麼緊湊,但可以透過壓縮大幅減少其大小。
Serialization 排除非公共成員和唯讀成員,除非透過屬性和建構函式進行特別處理。 System.Text.Json 也支援 自訂序列化和反序列化,以更好地控制類型與 JSON 之間的轉換。 System.Text.Json 不支援 [Serializable]
屬性。
使用 DataContractSerializer 的 XML
DataContractSerializer 是在 .NET Framework 3.0 中引入的,用於序列化和還原序列化在 Windows Communication Foundation (WCF) 訊息中傳送的資料。
DataContractSerializer 是 XML 串行化程式,完全支援 BinaryFormatter
所使用的串行化程序設計模型,這表示它接受 ISerializable的 [Serializable]
屬性和實作。 因此,它是最容易進行移轉的序列化程式。 但它需要事先指定已知類型 (但大多數 .NET 集合和基本類型都在預設的允許清單中,無需特別指定)。
雖然 DataContractSerializer
在從 BinaryFormatter 移轉時具有那些功能的優點,但它並不像其他選擇那樣現代或高效能。
移轉至 DataContractSerializer (XML)。
警告
請不要將 DataContractSerializer 與 NetDataContractSerializer 混淆。 NetDataContractSerializer 會識別為 危險的串行化程式。
使用 MessagePack 的二進位
MessagePack 是壓縮的二進位串行化格式,相較於 JSON 和 XML,訊息大小較小。 開放原始碼的 C# 用 MessagePack 庫具有高效能,並提供內建的超快速 LZ4 壓縮,以進一步縮小資料大小。 當資料類型使用 DataContractSerializer
或該資源庫自有的屬性進行註解時,效果最佳。 它可以設定為支援 AOT 環境、非公共類型和成員,以及唯讀類型和成員。
使用 protobuf-net 的二進位
protobuf-net 連結庫是 .NET 的合約型串行化程式,其使用二進位 通訊協定緩衝區 串行化格式。 該 API 遵循典型的 .NET 模式,並與 XmlSerializer
和 DataContractSerializer
大致相當。 這個受歡迎的資源庫功能豐富,能夠處理非公共類型和欄位,但在許多情境中確實需要對成員套用屬性。