是否可以使用协议缓冲区序列化 System.Object 对象列表 [英] Is it possible to serialize a list of System.Object objects using protocol buffers

查看:21
本文介绍了是否可以使用协议缓冲区序列化 System.Object 对象列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个各种数据类型(DateTime、int、decimal、string)的对象列表.

ListmyObjects = new List();myObjects.Add(3);myObjects.Add(3.9m);myObjects.Add(DateTime.Now);myObjects.Add("你好");

我能够使用 protobuf-net 序列化这个列表,但反序列化总是抛出异常:附加信息:类型不是预期的,并且不能推断出合同:System.Object".

using (var ms = new MemoryStream()){Serializer.Serialize(ms, list2);var 字节 = ms.ToArray();ms.Position = 0;var clone = Serializer.Deserialize(typeof(List), ms);//抛出异常}

我没有任何明确的合同,我想这就是问题所在?但是,我知道序列化对象的预期类型是什么,但我如何告诉 protobuf-net?

解决方案

检查这些以了解为什么这是一种方法:

  1. 对无参数构造函数的需求

  2. 为什么动态而不是对象不起作用

  3. 为什么 DynamicType=true 不会工作

  4. 需要抽象基类和具体实现,由 protobuf-net 的创建者提供p>

  5. 为什么没有序列化程序对象

抽象基础

 [ProtoContract][ProtoInclude(1, typeof(ObjectWrapper))][ProtoInclude(2, typeof(ObjectWrapper))][ProtoInclude(3, typeof(ObjectWrapper))][ProtoInclude(4, typeof(ObjectWrapper))]抽象类 ObjectWrapper {受保护的 ObjectWrapper() {}抽象公共对象 ObjectValue { get;放;}}

实施

 [ProtoContract()]类 ObjectWrapper: 对象包装器{公共 ObjectWrapper(): base() { }公共 ObjectWrapper(T t) { this.Value = t;}[ProtoIgnore()]公共覆盖对象 ObjectValue{得到 { 返回值;}设置{值=(T)值;}}[ProtoMember(1)]公共 T 值 { 得到;放;}}

测试

 var myObjects = new List();myObjects.Add(new ObjectWrapper(3));myObjects.Add(new ObjectWrapper(3.9m));myObjects.Add(new ObjectWrapper (DateTime.Now));myObjects.Add(new ObjectWrapper ("HELLO"));var clone = Serializer.DeepClone(myObjects);

I have a list of objects of various data types (DateTime, int, decimal, string).

List<object> myObjects = new List<object>();
myObjects.Add(3);
myObjects.Add(3.9m);
myObjects.Add(DateTime.Now);
myObjects.Add("HELLO");

I was able to serialize this list using protobuf-net, but deserialization always throws the exception: "Additional information: Type is not expected, and no contract can be inferred: System.Object".

using (var ms = new MemoryStream())
{
    Serializer.Serialize(ms, list2);
    var bytes = ms.ToArray();
    ms.Position = 0;
    var clone = Serializer.Deserialize(typeof(List<object>), ms); //Throws exception
}

I don't have any explicit contract, I suppose that is the problem? However, I do know what are the expected types of serialized objects, but how do I tell to protobuf-net?

解决方案

Check these to see why this is a way to go:

  1. The need for a parameterless constructor

  2. why dynamic instead of object wouldn't have worked

  3. why DynamicType=true wouldn't have worked

  4. the need for an abstract base class and concrete implementations, by the creator of protobuf-net

  5. why no serializer for object

Abstract base

    [ProtoContract]
    [ProtoInclude (1, typeof(ObjectWrapper<int>))]
    [ProtoInclude(2, typeof(ObjectWrapper<decimal>))]
    [ProtoInclude(3, typeof(ObjectWrapper<DateTime>))]
    [ProtoInclude(4, typeof(ObjectWrapper<string>))]
    abstract class ObjectWrapper {
        protected ObjectWrapper() {}
        abstract public object ObjectValue { get; set; }
    }

Implementation

    [ProtoContract()]
    class ObjectWrapper<T> : ObjectWrapper
    {
        public ObjectWrapper(): base() { }
        public ObjectWrapper(T t) { this.Value = t; }

        [ProtoIgnore()]
        public override object ObjectValue
        {
            get { return Value; }
            set { Value = (T)value; }
        }

        [ProtoMember(1)]
        public T Value { get; set; }
    }

Test

        var myObjects = new List<ObjectWrapper>();
        myObjects.Add(new ObjectWrapper<int>(3));
        myObjects.Add(new ObjectWrapper<decimal>(3.9m));
        myObjects.Add(new ObjectWrapper<DateTime> (DateTime.Now));
        myObjects.Add(new ObjectWrapper<string> ("HELLO"));
        var clone = Serializer.DeepClone(myObjects);

这篇关于是否可以使用协议缓冲区序列化 System.Object 对象列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆