順序に依存するのではなく、値に依存します。prototobuf(意味:googleによって定義された仕様。特にprotobuf-netではありません)は非常に簡潔です。あなたがネットワーク上で得るのは、あなたが何を手に入れようとしているのかをあなたに告げる数値識別子だけです。
最初にプロパティ/フィールド(、など)を検討する場合.Name
、これは、(たとえば)ワイヤ上.DateOfBirth
のキーとプロパティの間のマッピング方法です。もちろん、<===>のときにデータを保存し、気が変わって<===>と<=== >のときに読み返すと、大きな問題が発生します。フィールド番号のマッピングは、契約の重要な部分です。古いデータを読み取る必要がある場合は、フィールド番号のマッピングを変更しないでください(カスタムモデルといくつかのトリックを含む、いくつかの制限された方法がありますが、楽しいことは何もありません)。17
.Name
Name
17
Name
22
ShoeSize
17
今; 継承について考えてみましょう。protobufは継承を定義しません; とにかく。便宜上、protobuf-netは、継承をサブオブジェクトのカプセル化としてモデル化することにより、継承を機能させるメカニズムを提供します。これは、マッピングDogBarkedEvent
<===>が後の/の例8500
と基本的に変わらないことを意味します。気が変わって別のフィールド番号を使用すると、失敗します。Name
ShoeSize
したがって、追加/削除/名前変更された他のサブクラスの数に関係なく、DogBarkedEvent
毎回同じキーを生成する堅牢で反復可能な方法が必要です。最も簡単な方法は、などの属性を使用すること[ProtoInclude(...)]
です。これは、コード内で固定され、静的であるためです。それが望ましくない場合は、マップのある種の外部ストレージが推奨されます。フラットテキストファイルで十分です。解析して適用するだけです。すなわち
My.NameSpace.DogBarkedEvent=8500
My.NameSpace.DogBarkedEvent2=8501
また、使用したくない理由によっても異なります[ProtoInclude(...)]
。これがコードファイルが生成されたためである場合は、partial
クラスを検討してください。
namespace My.NameSpace
{
[ProtoInclude(8500, typeof(DogBarkedEvent))]
[ProtoInclude(8501, typeof(DogBarkedEvent2))]
partial class MyParentType {}
}
問題が、コードでライブラリ固有の型を使用したくないということである場合。次に、独自の属性を宣言し、モデルを構成するときにそれを読みます。例えば:
[SubtypeKey(8500, typeof(DogBarkedEvent))]
[SubtypeKey(8501, typeof(DogBarkedEvent2))]
(およびでフェッチAttribute.GetCustomAttribute
)