ProtoInclude属性意味着什么(在protobuf-net中)

在ProtoBuf-Net实现中, ProtoInclude属性意味着什么,它有什么作用?

一个例子将不胜感激。

我在这篇文章中看到了它,我不确定它是做什么的。 这个例子是:

[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; } } } 

另外,有没有办法使用protogen工具生成这种inheritance?

对不起,我不是故意错过这个 – 唉,我什么都看不到。

鉴于问题的具体细节,我将假设你至少熟悉.proto; 如果我错了,请纠正我。

[ProtoInclude]XmlSerializer [XmlInclude]非常相似 – 或者DataContractSerializer [KnownType] – 它允许它在(反)序列化期间识别类型的子类。 唯一的另一件事是它需要一个标签(数字)来标识每个子类型(必须是唯一的,而不是与父类型的任何字段冲突)。

重新原型:不; 根本规范(谷歌)根本没有提供inheritance,因此protogen(通过.proto)没有机制来表达这一点。 protobuf-net提供inheritance支持作为扩展 ,但它仍然以一种方式使消息与其他实现保持线路兼容。 在推动, 也许我可以通过谷歌规范中的新扩展属性添加protogen支持,但我还没有这样做。

所以; 看一下这个例子; 表示BaseMessageBeginRequest之间的inheritance关系; 不管你是否这样做:

 Serialize(...) Serialize(...) 
  • 无论哪种方式,它将从基地( BaseMessage )开始并向上工作; 这不完全正确 – 它以BeginRequest开头写入数据 (因此它知道我们在反序列化期间尽早拥有BeginRequest )。 重要的是包含任何父契约类型的字段,并且序列化程序查看传入的实际对象 – 而不仅仅是您的类型。

同样,在deserilaization期间,无论您是否使用:

 Deserialize(...) Deserialize(...) 

你会得到你实际序列化的类型(可能是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] 

(在这种情况下,子消息的主体是空的)

这涵盖了吗?