How can I send multiple types of objects across Protobuf?

前端 未结 2 1683
轮回少年
轮回少年 2020-12-30 09:36

I\'m implementing a client-server application, and am looking into various ways to serialize and transmit data. I began working with Xml Serializers, which worked rather wel

2条回答
  •  一生所求
    2020-12-30 10:06

    I've come up with another solution, but I decided to put it as an answer, instead of in the question, because that makes more sense to me. It's pretty ugly, in my opinion, and I've been warned against using reflection, so please comment on it or provide better answers if you have them. Thanks!


    class Program
    {
        static void Main(string[] args)
        {
            Person person = new Person
            {
                Id = 12345,
                Name = "Fred",
                Address = new Address
                {
                    Line1 = "Flat 1",
                    Line2 = "The Meadows"
                }
            };
            object value;
            using (Stream stream = new MemoryStream())
            {
                Send(stream, person);
                stream.Position = 0;
                value = Read(stream);
                person = value as Person;
            }
        }
    
        static void Send(Stream stream, T value)
        {
            Header header = new Header()
            {
                Guid = Guid.NewGuid(),
                Type = typeof(T)
            };
            Serializer.SerializeWithLengthPrefix
    (stream, header, PrefixStyle.Base128); Serializer.SerializeWithLengthPrefix(stream, value, PrefixStyle.Base128); } static object Read(Stream stream) { Header header; header = Serializer.DeserializeWithLengthPrefix
    (stream, PrefixStyle.Base128); MethodInfo m = typeof(Serializer).GetMethod("DeserializeWithLengthPrefix", new Type[] {typeof(Stream), typeof(PrefixStyle)}).MakeGenericMethod(header.Type); Object value = m.Invoke(null, new object[] {stream, PrefixStyle.Base128} ); return value; } } [ProtoContract] class Header { public Header() { } [ProtoMember(1, IsRequired = true)] public Guid Guid { get; set; } [ProtoIgnore] public Type Type { get; set; } [ProtoMember(2, IsRequired = true)] public string TypeName { get { return this.Type.FullName; } set { this.Type = Type.GetType(value); } } } [ProtoContract] class Person { [ProtoMember(1)] public int Id { get; set; } [ProtoMember(2)] public string Name { get; set; } [ProtoMember(3)] public Address Address { get; set; } } [ProtoContract] class Address { [ProtoMember(1)] public string Line1 { get; set; } [ProtoMember(2)] public string Line2 { get; set; } }

提交回复
热议问题