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

时间:2009-06-03 22:43:44

标签: c# .net protocol-buffers protobuf-net

ProtoBuf-Net实施中, ProtoInclude 属性是什么意思,它有什么作用?

一个例子将不胜感激。

我看到它in this post而且我不确定它是做什么的。例子是:

[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 工具生成这种继承?

1 个答案:

答案 0 :(得分:22)

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

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

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

Re protogen:nope;基础规范(通过谷歌)没有提供继承的所有,因此protogen(通过.proto)没有机制来表达这一点。 protobuf-net提供继承支持作为扩展,但它仍然以使得消息与其他实现有线兼容的方式进行。在推动,也许我可以通过谷歌规范中的新扩展属性添加protogen支持,但我还没有这样做。

因此;看一下这个例子;表示[KnownType]DataContractSerializer之间的继承关系;不管你是否这样做:

BaseMessage
  • 无论哪种方式,它都会从基地(BeginRequest)开始向上工作;这不是完全为真 - 它以Serialize<BaseMessage>(...) Serialize<BeginRequest>(...) 开头写出数据(这样它就知道我们在BaseMessage期间尽早发现BeginRequest反序列化)。重要的是包含任何父合同类型的字段,并且序列化程序会查看传入的实际对象 - 而不仅仅是所说的类型。< / LI>

同样,在去除分类期间,无论您是否使用:

BeginRequest

您将获得实际序列化的类型(可能是Deserialize<BaseMessage>(...) Deserialize<BeginRequest>(...) )。

在引擎盖下,出于兼容性目的(使用宽协议缓冲区规范),这类似于编写类似的内容(原谅任何错误,我的.proto生锈):

BeginRequest

(覆盖可能不应指定message BaseMessage { optional BeginRequest beginRequest = 50; optional uint32 messageType = 1; } message BeginRequest { } ,顺便说一句。

通常情况下,它会按升序标记顺序写入字段,但为了实现高效的反序列化,引擎会选择先编写子类数据 (规范明确允许) - 即写入类似的东西(你必须想象二进制......):

[ProtoMember]

(在这种情况下,子消息的正文是空的)

这涵盖了吗?