ProtoInclude 属性は何を意味しますか (protobuf-net 内)
-
09-09-2019 - |
質問
の中に ProtoBuf-Net 実装、何をするのか プロトインクルード 属性とは何を意味しますか?そしてそれは何をするのですか?
一例を挙げていただければ幸いです。
私はそれを見た この投稿で それが何をするのか分かりません。その例は次のとおりです。
[Serializable,
ProtoContract,
ProtoInclude(50, typeof(BeginRequest))]
abstract internal class BaseMessage
{
[ProtoMember(1)]
abstract public UInt16 messageType { get; }
}
[Serializable,
ProtoContract]
internal class BeginRequest : BaseMessage
{
[ProtoMember(1)]
public override UInt16 messageType
{
get { return 1; }
}
}
また、を使用してそのような継承を生成する方法はありますか? プロトゲン 道具?
解決
申し訳ありませんが、これを見逃すつもりはありませんでした。残念ながら、すべてが表示されているわけではありません。
質問の詳細を考慮すると、あなたは少なくとも .proto については多少なりとも知っていると仮定します。私が間違っていたら訂正してください。
[ProtoInclude]
よく似た働きをします [XmlInclude]
のために XmlSerializer
- または [KnownType]
のために DataContractSerializer
- これにより、(逆) シリアル化中に型のサブクラスを認識できるようになります。唯一の追加事項は、各サブタイプを識別するためにタグ (番号) が必要であることです (これは一意である必要があり、親タイプのフィールドと衝突してはなりません)。
プロトゲンに関して:いいえ;基礎となる仕様 (Google による) には継承の規定がありません 全然, したがって、protogen (.proto 経由) にはこれを表現するメカニズムがありません。protobuf-net は継承サポートを提供します。 拡大, ただし、他の実装とのワイヤ互換性のあるメッセージを残す方法で実行されます。一気に、 多分 Google 仕様の新しい拡張プロパティを介してプロトジェンのサポートを追加できますが、まだこれを行っていません。
それで;例を見てみましょう。間の継承関係を表す BaseMessage
そして BeginRequest
;あなたがそうするかどうかに関係なく:
Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
- いずれにしても、ベースから始まります(
BaseMessage
)そして上向きに働きます。そうでないのは その通り true - を書き込みます データ で始まりますBeginRequest
(それは、私たちが持っていることを知るためですBeginRequest
逆シリアル化中にできるだけ早く)。重要なことは、親コントラクト タイプのフィールドが含まれており、シリアライザーは 実際の 渡されるオブジェクト - 型だけではありません 言う それはそうです。
同様に、非シリアル化中は、以下を使用するかどうかに関係なく、以下を使用します。
Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)
実際にシリアル化した型 (おそらく BeginRequest
).
ボンネットの下では、(幅広いプロトコル バッファ仕様との) 互換性を目的として、これは次のようなものを書くのと似ています (エラーはご容赦ください。私の .proto は錆びています)。
message BaseMessage {
optional BeginRequest beginRequest = 50;
optional uint32 messageType = 1;
}
message BeginRequest {
}
(オーバーライドではおそらく指定すべきではありません [ProtoMember]
, ところで。
通常、フィールドはタグの昇順で書き込まれますが、効率的な逆シリアル化を行うために、エンジンは生意気にサブクラス データを書き込むことを選択します。 初め (これは仕様で明示的に許可されています) - つまり次のようなものを書きます (バイナリを想像する必要があります...):
[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]
(この場合、サブメッセージの本文は空です)
それはカバーされますか?