次の方法で共有


protobuf-net (バイナリ) への移行

protobuf-net ライブラリは、バイナリ Protocol Buffersserialization形式を使用する .NET 用のコントラクト ベースのシリアライザーです。 この API は一般的な .NET パターンに従っていて、XmlSerializerDataContractSerializer におおむね相当します。

protobuf-net の一部の動作と機能は、BinaryFormatter からの移行で優れていて、多くのシナリオではメンバーに属性を適用する必要があります。

  • 既定では、パブリック型と非パブリック型の両方がシリアル化可能であり、シリアライザーはパラメーターなしのコンストラクターを必要とします。
  • protobuf-net は、シリアル化可能なそれぞれの型に [ProtoContract] 属性で注釈を付けることを必要とします。この属性は必要に応じて、SkipConstructor = true プロパティを指定できます。これにより、特定のコンストラクターが "必要なくなります"。
  • シリアル化可能なすべての非静的フィールドとプロパティには、[ProtoMember(int identifier)] 属性を使用して注釈を付ける必要があります。 メンバー名はデータにエンコードされません。 代わりに、各メンバーを識別するために、その型内で一意である必要がある正の整数をユーザーが選択する必要があります。
  • 各型で、既知のサブタイプを持つ [ProtoInclude(...)] 属性を使用して継承を明示的に宣言する必要があります。
  • 読み取り専用フィールドが既定でサポートされます。
  • 一方、一部の属性付けされていないタプルのような型は、"コンストラクター パターン" によって認識されます。宣言されたすべてのパブリック メンバーに一致するパラメーターを持つコンストラクターを持つ型はタプルとして解釈され、そのメンバーの識別子を推論するためにパラメーターの順序が使用されます。
  • protobuf-net.BuildTools デザイン時パッケージの使用を強くお勧めします。これにより、コンパイル時に一般的なエラーの警告が表示されます。

ステップ バイ ステップ移行

  1. BinaryFormatter が使用されているすべての箇所を見つけます。
  2. 変更を検証してバグの発生を回避できるように、serializationコード パスがテストでカバーされていることを確認します。
  3. protobuf-net パッケージ (および必要に応じて protobuf-net.BuildTools) をインストールします。
  4. BinaryFormatter でシリアル化されているすべての型を検索します。
  5. 変更できる型の場合:
    • [Serializable] のマークが付けられているすべての型に、[ProtoContract] 属性を使用して注釈を付けるか、ISerializable インターフェイスを実装します。 これらの型が、DataContractSerializer などの異なるシリアライザーを使用する可能性がある他のアプリに公開 (ライブラリを作成しているなど) されていない場合は、[Serializable]ISerializable 注釈を削除できます。
    • 派生型の場合は、基本型に [ProtoInclude(...)] を適用します (以下の例を参照)。
    • パラメーターを受け取るコンストラクターを宣言するすべての型に対して、パラメーターなしのコンストラクターを追加するか、[ProtoContract] 属性に SkipConstructor = true を指定します。 protobuf-net の要件を (誤って削除されることがないように) 説明するコメントを残します。
    • シリアル化するすべてのメンバー (フィールドとプロパティ) に [ProtoMember(int identifier)] のマークを付けます。 すべての識別子は 1 つの型内で一意である必要がありますが、継承が有効になっている場合は、同じ数値をサブタイプで再利用できます。
  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; }
}