问题
What's the order of deserialization of members in protobuf-net? Is it in order of tag numbers, in order of declaration, something else, or not guaranteed?
I'm relying on this for my workaround for the problem where protobuf-net doesn't support most types of jagged arrays. I have a custom LinearAdapter class that presents the jagged array as an IEnumerable<T> (with an Add method). My main data representation is padded with zeros at the sides, with a variable padding size, so, on deserializing, in LinearAdapter I first read the already-deserialized padding size, so I can deserialize the array correctly.
回答1:
Your title asks about deserialization - for which the answer is usually "in the order they are encountered in the stream" - i.e. it assigns data directly to members (or adds to lists) as it sees it. Specifically, lists are processed as follows
- (read header that maps to a list field)
- get existing list from member, or create new
- [*] read value from stream
- add to list
- peek at next header; if the same field, consume header and resume from [*]
- assign list to member if necessary
single basic values, on the other hand, are processed as:
- (read header that maps to a value field)
- read value from stream
- assign value to member
(note no looping)
more complex values (objects) would be processed as:
- (read header that maps to an object field)
- read existing object from member
- merge sub-object from sub-stream, or create new object if trivial
- assign object to member if necessary
There is a subtle exception to this, in the case of "tuple-like" data (with implicit contracts), where for implementation reasons the values are all held in locals until the object's stream is consumed, and then the constructor is invoked (the order of the parameters to the constructor is implicitly the tag ordering here):
- prepare a local variable per field (default values, etc)
- consume the sub-stream, with the logic as above, but assigning to the local variables, not members
- invoke the constructor
If you mean "how is it serialized", then it is serialized in ascending tag-order (as per guidance in the wire spec) - however, it makes a slight exception here in the case of inheritance (which it implements on the wire via a sub-object for the sub-class).
来源:https://stackoverflow.com/questions/8808290/order-of-deserialization-in-protobuf-net