protobuf and List<object> - how to serialize / deserialize?

前端 未结 2 1604
甜味超标
甜味超标 2020-12-06 03:20

I have a List with different types of objects in it like integers, strings, and custom types. All custom types are protobuf-adjusted. What I wanna
2条回答
  •  萌比男神i
    2020-12-06 03:43

    (disclosure: I'm the author of protobuf-net)

    BinaryFormatter is a metadata-based serializer; i.e. it sends .NET type information about every object serialized. protobuf-net is a contract-based serializer (the binary equivalent of XmlSerializer / DataContractSerializer, which will also reject this).

    There is no current mechanism for transporting arbitrary objects, since the other end will have no way of knowing what you are sending; however, if you have a known set of different object types you want to send, there may be options. There is also work in the pipeline to allow runtime-extensible schemas (rather than just attributes, which are fixed at build) - but this is far from complete.


    This isn't ideal, but it works... it should be easier when I've completed the work to support runtime schemas:

    using System;
    using System.Collections.Generic;
    using ProtoBuf;
    [ProtoContract]
    [ProtoInclude(10, typeof(DataItem))]
    [ProtoInclude(11, typeof(DataItem))]
    [ProtoInclude(12, typeof(DataItem))]
    [ProtoInclude(13, typeof(DataItem))]
    abstract class DataItem {
        public static DataItem Create(T value) {
            return new DataItem(value);
        }
        public object Value {
            get { return ValueImpl; }
            set { ValueImpl = value; }
        }
        protected abstract object ValueImpl {get;set;}
        protected DataItem() { }
    }
    [ProtoContract]
    sealed class DataItem : DataItem {
        public DataItem() { }
        public DataItem(T value) { Value = value; }
        [ProtoMember(1)]
        public new T Value { get; set; }
        protected override object ValueImpl {
            get { return Value; }
            set { Value = (T)value; }
        }
    }
    [ProtoContract]
    public class Foo {
        [ProtoMember(1)]
        public string Bar { get; set; }
        public override string ToString() {
            return "Foo with Bar=" + Bar;
        }
    }
    static class Program {
        static void Main() {
            var items = new List();
            items.Add(DataItem.Create(12345));
            items.Add(DataItem.Create(DateTime.Today));
            items.Add(DataItem.Create("abcde"));
            items.Add(DataItem.Create(new Foo { Bar = "Marc" }));
            items.Add(DataItem.Create(67890));
    
            // serialize and deserialize
            var clone = Serializer.DeepClone(items);
            foreach (DataItem item in clone) {
                Console.WriteLine(item.Value);
            }
        }
    }
    

提交回复
热议问题