共用方式為


移轉到 protobuf-net (二進位)

protobuf-net 連結庫是 .NET 的合約型串行化程式,其使用二進位 通訊協定緩衝區 串行化格式。 該 API 遵循典型的 .NET 模式,並與 XmlSerializerDataContractSerializer 大致相當。

Protobuf-net 的某些行為和功能在 BinaryFormatter 移轉期間將會值得注意,而且許多案例都需要將屬性套用至成員。

  • 根據預設,公用和非公用類型都是可序列化的,而序列化程式需要無參數建構函式。
  • protobuf-net 需要以 [ProtoContract] 屬性註釋每個可序列化的類型;這個屬性可以選擇性地指定 SkipConstructor = true 屬性,以移除任何特定建構函式的需求。
  • 每個可序列化的非靜態欄位和屬性都必須以 [ProtoMember(int identifier)] 屬性註釋。 成員名稱不會在資料中編碼。 相反地,用戶必須挑選正整數,以識別該類型內必須是唯一的每個成員。
  • 繼承必須透過具有已知子類型的每個類型上的 [ProtoInclude(...)] 屬性明確宣告。
  • 預設支援唯讀欄位。
  • 或者,建構函式模式可辨識一些非屬性化元組類型;具有符合所有宣告公用成員之參數的類型將會解譯為元組,而且參數順序將用來推斷該成員的標識符。
  • 強烈建議使用 protobuf-net.BuildTools 設計時間套件;這會提供常見錯誤的編譯時期警告。

逐步移轉

  1. 尋找 BinaryFormatter 的所有使用方式。
  2. 請確定測試涵蓋串行化程式代碼路徑,因此您可以驗證您的變更,並避免引入錯誤。
  3. 安裝 protobuf-net 套件 (以及選擇性的 protobuf-net.BuildTools) 。
  4. 尋找使用 BinaryFormatter 序列化的所有類型。
  5. 針對您可以修改的類型:
    • [ProtoContract] 屬性註釋所有標示 [Serializable] 或實作 ISerializable 介面的類型。 如果這些類型未公開給其他應用程式 (例如:您正在撰寫連結庫) ,可能會使用不同的序列化程式,例如 DataContractSerializer,您可以移除 [Serializable]ISerializable 批注。
    • 針對衍生類型,請套用 [ProtoInclude(...)] 至其基底類型 (請參閱下列範例) 。
    • 針對宣告任何接受參數的建構函式,新增無參數建構函式或在 SkipConstructor = true 屬性上指定 [ProtoContract]。 留下一個註解,解釋 protobuf-net 需求 (所以沒有人會意外移除) 。
    • 標記您想要使用 [ProtoMember(int identifier)] 序列化的所有成員 (欄位和屬性) 。 所有標識碼在單一類型內都必須是唯一的,但如果啟用繼承,可以在子類型中重複使用相同的數位。
  6. 針對您無法修改的類型:
    • 針對 .NET 本身所提供的類型,您可以使用 ProtoBuf.Meta.RuntimeTypeModel.Default.CanSerialize(Type type) API 來檢查 protobuf-net 原生支持的類型。
    • 您可以建立專用資料傳輸物件 (DTO) ,並據以進行對應 (您可以使用隱含轉換運算符進行對應) 。
    • 使用 RuntimeTypeModel API 來定義屬性允許的所有項目。
  7. 使用 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; }
}