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支持,但我还没有这样做。
所以; 看一下这个例子; 表示BaseMessage
和BeginRequest
之间的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]
(在这种情况下,子消息的主体是空的)
这涵盖了吗?