移轉到 protobuf-net (二進位)
protobuf-net 連結庫是 .NET 的合約型串行化程式,其使用二進位 通訊協定緩衝區 串行化格式。 該 API 遵循典型的 .NET 模式,並與 XmlSerializer
和 DataContractSerializer
大致相當。
Protobuf-net 的某些行為和功能在 BinaryFormatter 移轉期間將會值得注意,而且許多案例都需要將屬性套用至成員。
- 根據預設,公用和非公用類型都是可序列化的,而序列化程式需要無參數建構函式。
- protobuf-net 需要以
[ProtoContract]
屬性註釋每個可序列化的類型;這個屬性可以選擇性地指定SkipConstructor = true
屬性,以移除任何特定建構函式的需求。 - 每個可序列化的非靜態欄位和屬性都必須以
[ProtoMember(int identifier)]
屬性註釋。 成員名稱不會在資料中編碼。 相反地,用戶必須挑選正整數,以識別該類型內必須是唯一的每個成員。 -
繼承必須透過具有已知子類型的每個類型上的
[ProtoInclude(...)]
屬性明確宣告。 - 預設支援唯讀欄位。
- 或者,建構函式模式可辨識一些非屬性化元組類型;具有符合所有宣告公用成員之參數的類型將會解譯為元組,而且參數順序將用來推斷該成員的標識符。
- 強烈建議使用
protobuf-net.BuildTools
設計時間套件;這會提供常見錯誤的編譯時期警告。
逐步移轉
- 尋找
BinaryFormatter
的所有使用方式。 - 請確定測試涵蓋串行化程式代碼路徑,因此您可以驗證您的變更,並避免引入錯誤。
- 安裝
protobuf-net
套件 (以及選擇性的protobuf-net.BuildTools
) 。 - 尋找使用
BinaryFormatter
序列化的所有類型。 - 針對您可以修改的類型:
- 以
[ProtoContract]
屬性註釋所有標示[Serializable]
或實作ISerializable
介面的類型。 如果這些類型未公開給其他應用程式 (例如:您正在撰寫連結庫) ,可能會使用不同的序列化程式,例如DataContractSerializer
,您可以移除[Serializable]
和ISerializable
批注。 - 針對衍生類型,請套用
[ProtoInclude(...)]
至其基底類型 (請參閱下列範例) 。 - 針對宣告任何接受參數的建構函式,新增無參數建構函式或在
SkipConstructor = true
屬性上指定[ProtoContract]
。 留下一個註解,解釋 protobuf-net 需求 (所以沒有人會意外移除) 。 - 標記您想要使用
[ProtoMember(int identifier)]
序列化的所有成員 (欄位和屬性) 。 所有標識碼在單一類型內都必須是唯一的,但如果啟用繼承,可以在子類型中重複使用相同的數位。
- 以
- 針對您無法修改的類型:
- 針對 .NET 本身所提供的類型,您可以使用
ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type)
API 來檢查 protobuf-net 原生支持的類型。 - 您可以建立專用資料傳輸物件 (DTO) ,並據以進行對應 (您可以使用隱含轉換運算符進行對應) 。
- 使用
RuntimeTypeModel
API 來定義屬性允許的所有項目。
- 針對 .NET 本身所提供的類型,您可以使用
- 使用
BinaryFormatter
取代ProtoBuf.Serializer
。
-[Serializable]
+[ProtoContract]
+[ProtoInclude(2, typeof(Point2D))]
public class Point1D
{
+ [ProtoMember(1)]
public int X { get; set; }
}
-[Serializable]
+[ProtoContract]
public class Point2D : Point1D
{
+ [ProtoMember(2)]
public int Y { get; set; }
}