申し訳ありませんが、これを見逃すつもりはありませんでした。残念ながら、すべてが表示されていません。
質問の詳細を考えると、少なくとも .proto に精通していると仮定します。私が間違っている場合は修正してください。
[ProtoInclude]
[XmlInclude]
for XmlSerializer
- または[KnownType]
for -のようDataContractSerializer
に機能し、(逆) シリアル化中に型のサブクラスを認識することができます。唯一の追加事項は、各サブタイプを識別するためにタグ (番号) が必要なことです (これは一意である必要があり、親タイプのフィールドと衝突しない必要があります)。
プロトゲンについて: いいえ。基礎となる仕様 (Google による) は継承をまったく規定していないため、protogen (.proto 経由) にはこれを表現するメカニズムがありません。protobuf-net は拡張機能として継承サポートを提供しますが、他の実装とのワイヤー互換性のあるメッセージを残す方法でそれを行います。プッシュで、Google仕様の新しい拡張プロパティを介してprotogenサポートを追加できるかもしれませんが、まだこれを行っていません.
そう; 例を見てください。と の間の継承関係をBaseMessage
表すBeginRequest
; あなたがするかどうかに関係なく:
Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
- どちらの方法でも、ベース (
BaseMessage
) から開始し、上に向かって動作します。これは正確には当てはまりません -データを最初から書き込みます (デシリアライゼーション中のできるだけ早い段階BeginRequest
で があることを認識できるようにするため)。BeginRequest
重要なことは、任意の親コントラクト型のフィールドが含まれていることです。シリアライザーは、渡された実際のオブジェクトを調べます-あなたが言う型だけではありません。
同様に、以下を使用するかどうかに関係なく、デシリアライゼーション中に:
Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)
実際にシリアル化した型 (おそらく a BeginRequest
) を取得します。
ボンネットの下では、(ワイド プロトコル バッファ仕様との) 互換性のために、これは次のような記述に似ています (エラーを許してください。私の .proto は錆びています):
message BaseMessage {
optional BeginRequest beginRequest = 50;
optional uint32 messageType = 1;
}
message BeginRequest {
}
(オーバーライドはおそらく を指定すべきではありません[ProtoMember]
、btw.
通常、タグの昇順でフィールドを書き込みますが、効率的な逆シリアル化を行うために、エンジンは最初にサブクラス データを書き込むことを生意気に選択します(これは仕様で明示的に許可されています)。つまり、次のように書き込みます (バイナリ...):
[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]
(この場合、サブメッセージの本文は空です)
それはそれをカバーしていますか?