there are several different questions here, so I’ll answer what I see: if I missed something, just let me know.
First, as noted, a MemoryStream is the most common way to access bytes []. This is consistent with most serializers — for example, the XmlSerializer, BinaryFormatter, and DataContractSerializer also do not have “overload [] bytes”, but will accept a MemoryStream.
Generics: you do not need to use generics; v1 has a Serializer.NonGeneric that wraps this from you. In v2, the "core" is not shared and can be accessed through RuntimeTypeModel.Default; Of course Serializer and Serializer.NonGeneric continue to work.
In order to include the type: yes, the protobuf spec assumes that the receiver knows what type of data they return. A simple option here is to use a simple wrapper object as the “root” object with several typed properties for the data (only one of which is not null). Another option would be spring from the built-in support for inheritance via ProtoInclude (note: as an implementation detail, these two approaches are identical).
In your specific example, perhaps consider:
[ProtoContract] [ProtoInclude(1, typeof(Message<Foo>))] .... More as needed [ProtoInclude(8, typeof(Message<Bar>))] public abstract class Message { } [ProtoContract] public class Message<T> : Message { ... }
Then just serialize with <Message> - the API will automatically create the correct type.
In recent builds, there is also DynamicType , which includes type data for you, for example:
[ProtoContract] public class MyRoot { [ProtoMember(1, DynamicType=true)] public object Value { get; set; } }
This will work for any value that contains an instance of a contract type (but not for primitives and ideally does not include inheritance).
Marc gravell
source share