C# ProtoInclude 属性是什么意思(在 protobuf-net 中)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/947666/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What does the ProtoInclude attribute mean (in protobuf-net)
提问by Mike Dinescu
In the ProtoBuf-Netimplementation, what does the ProtoIncludeattribute mean, and what does it do?
在ProtoBuf-Net实现中,ProtoInclude属性是什么意思,它有什么作用?
An example would be appreciated.
一个例子将不胜感激。
I saw it in this postand I'm not sure what it does. The example was:
[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; }
}
}
Also, is there a way to generate such inheritance using the protogentool?
另外,有没有办法使用protogen工具生成这样的继承?
采纳答案by Marc Gravell
Sorry, I didn't mean to miss this one - alas, I don't see everything.
对不起,我不是故意错过这个 - 唉,我没有看到一切。
Given the specifics in the question, I'm going to assume that you are at least passingly familiar with .proto; correct me if I am wrong.
鉴于问题中的细节,我假设您至少对 .proto 非常熟悉;如果我错了,请纠正我。
[ProtoInclude]
works a lot like [XmlInclude]
for XmlSerializer
- or [KnownType]
for DataContractSerializer
- it allows it to recognise subclasses of a type during (de)serialization. The only additional thing is that it needs a tag (number) to identify each sub-type (that must be unique, and not clash with any of the fields from the parent type).
[ProtoInclude]
工作起来很像[XmlInclude]
for XmlSerializer
- 或[KnownType]
for DataContractSerializer
- 它允许它在(反)序列化期间识别类型的子类。唯一额外的事情是它需要一个标签(数字)来标识每个子类型(必须是唯一的,并且不能与父类型的任何字段冲突)。
Re protogen: nope; the underlying spec (by google) makes no provision for inheritance at all, so protogen (via .proto) has no mechanism to express this. protobuf-net provides inheritance support as an extension, but does it in a way that still leaves the messages wire-compatible with the other implementations. At a push, maybeI could add protogen support via the new extension properties in the google spec, but I haven't done this yet.
再原:不;基础规范(由谷歌),使得继承没有规定在所有的,所以硫辛酸(通过.proto)没有这样的机制来表达这一点。protobuf-net 提供继承支持作为扩展,但它的方式仍然使消息与其他实现保持兼容。在推动下,也许我可以通过 google 规范中的新扩展属性添加对 protogen 的支持,但我还没有这样做。
So; to look at the example; that expresses an inheritance relationship between BaseMessage
and BeginRequest
; regardless of whether you do:
所以; 看例子;表示BaseMessage
和之间的继承关系BeginRequest
;不管你是否:
Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
- either way, it will start at the base (
BaseMessage
) and work upwards; which isn't exactlytrue - it writes the datastarting withBeginRequest
(so that it knows we have aBeginRequest
as early as possible during deserialization). The important thing is that the fields from any parent contract types is included, and the serializer looks at the actualobject passed in - not just the type you sayit is.
- 无论哪种方式,它都会从底部 (
BaseMessage
) 开始并向上工作;这并不完全正确 - 它以( 以便它知道我们在反序列化过程中尽早知道我们有一个 )开头的数据。重要的是包含来自任何父合同类型的字段,并且序列化程序查看传入的实际对象 - 而不仅仅是您所说的类型。BeginRequest
BeginRequest
Likewise, during deserilaization, regardless of whether you use:
同样,在脱丝过程中,无论您是否使用:
Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)
you will get the type you actually serialized (presumably a BeginRequest
).
你会得到你实际序列化的类型(大概是 a BeginRequest
)。
Under the bonnet, for compatibility purposes (with the wide protocol buffers specification), this is similar to writing something like (forgive any errors, my .proto is rusty):
在引擎盖下,出于兼容性目的(使用广泛的协议缓冲区规范),这类似于编写类似的内容(请原谅任何错误,我的 .proto 已生锈):
message BaseMessage {
optional BeginRequest beginRequest = 50;
optional uint32 messageType = 1;
}
message BeginRequest {
}
(the override probably shouldn't specify [ProtoMember]
, btw.
(覆盖可能不应该指定[ProtoMember]
,顺便说一句。
Normally, it would write fields in ascending tag order, but to make for efficient deserialization the engine cheekily chooses to write the subclass data first(which is explicitly allowed by the spec) - i.e. it writes something like (you'll have to imagine the binary...):
通常情况下,它会写在上升标记顺序领域,而是要进行有效的反序列化引擎厚脸皮选择写子类数据第一(这是明确的规范允许的) -即它写像(你必须想象二进制...):
[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]
(in this case, the body of the sub-message is empty)
(在这种情况下,子消息的正文为空)
Does that cover it?
这涵盖了吗?