在里面 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 支持,但我还没有这样做。

所以;看一下例子;表示之间的继承关系 BaseMessageBeginRequest;无论你是否这样做:

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]

(本例中子消息正文为空)

这涵盖了吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top