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
- 它允许它在(反)序列化期间识别类型的子类。唯一额外的事情是它需要一个标签(数字)来标识每个子类型(必须是唯一的,并且不与父类型中的任何字段冲突)。
重新原:没有;底层规范(谷歌)没有提供继承的规定 根本不, ,所以 protogen (通过 .proto)没有机制来表达这一点。protobuf-net 提供继承支持 扩大, ,但这样做的方式仍然使消息与其他实现保持线路兼容。一推, 或许 我可以通过谷歌规范中的新扩展属性添加 protogen 支持,但我还没有这样做。
所以;看一下例子;表示之间的继承关系 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]
(本例中子消息正文为空)
这涵盖了吗?