Mik*_*scu 18 .net c# protocol-buffers 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; }
}
}
Run Code Online (Sandbox Code Playgroud)
另外,有没有办法使用protogen工具生成这种继承?
Mar*_*ell 23
对不起,我不是故意错过这个 - 唉,我什么都看不到.
鉴于问题的具体细节,我将假设你至少熟悉.proto; 如果我错了,请纠正我.
[ProtoInclude]就像很多[XmlInclude]的XmlSerializer-或[KnownType]为DataContractSerializer-它允许它在(反)序列识别类的子类.唯一的补充是它需要一个标记(数字)来标识每个子类型(必须是唯一的,而不是与父类型的任何字段冲突).
重新原型:不; 基础规范(由谷歌)未作任何规定继承可言,所以硫辛酸(通过.proto)没有这样的机制来表达这一点.protobuf-net提供继承支持作为扩展,但它仍然以一种方式使消息与其他实现保持线路兼容.在一推,也许我可以通过在谷歌规范新扩展属性添加硫辛酸的支持,但我没有这样做呢.
所以; 看一下这个例子; 表达BaseMessage和之间的继承关系BeginRequest; 不管你是否这样做:
Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
Run Code Online (Sandbox Code Playgroud)
BaseMessage)开始并向上工作; 这不完全正确 - 它以数据开头写入BeginRequest(因此它知道我们BeginRequest在反序列化期间尽可能早地获得).重要的是包含任何父契约类型的字段,并且序列化程序查看传入的实际对象 - 而不仅仅是您说的类型.同样,在deserilaization期间,无论您是否使用:
Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)
Run Code Online (Sandbox Code Playgroud)
你会得到你实际序列化的类型(大概是a BeginRequest).
在引擎盖下,出于兼容性目的(使用宽协议缓冲区规范),这类似于编写类似的东西(原谅任何错误,我的.proto生锈):
message BaseMessage {
optional BeginRequest beginRequest = 50;
optional uint32 messageType = 1;
}
message BeginRequest {
}
Run Code Online (Sandbox Code Playgroud)
(重写可能不应该指定[ProtoMember],顺便说一句.
通常情况下,它会写在上升标记顺序领域,而是要进行有效的反序列化引擎厚脸皮选择写子类数据第一(这是明确的规范允许的) -即它写像(你必须想象二进制...):
[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]
Run Code Online (Sandbox Code Playgroud)
(在这种情况下,子消息的主体是空的)
这涵盖了吗?
| 归档时间: |
|
| 查看次数: |
11404 次 |
| 最近记录: |