【问题标题】:Protobuf-net serialization error: Dynamic type is not a contract-type: Int32Protobuf-net 序列化错误:动态类型不是合约类型:Int32
【发布时间】:2020-06-24 12:10:08
【问题描述】:

我需要使用以下代码进行序列化和反序列化。但是我在序列化时总是收到“动态类型不是合同类型”错误。我被这个困住了。我需要以某种方式实现这一点有人可以帮助我吗?

using ProtoBuf;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;

namespace ProtoSerialization
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                byte[] arr;
                ClassA obj = new ClassA();
                obj.ColumnList = new List<int> {1 };
                using (var stream = new MemoryStream())
                {
                    ProtoBuf.Serializer.Serialize(stream, obj);
                    arr = stream.ToArray();
                }
                using(var stream=new MemoryStream(arr)) 
                {
                    var result = Serializer.Deserialize(typeof(ClassA), stream);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.ReadKey();
            }
        }
    }
    [ProtoContract]
    public class ClassA 
    {
        [ProtoMember(1,DynamicType =true)]
        public IList ColumnList;
    }
}

【问题讨论】:

  • 这里的目标是什么?例如,您想序列化一个可以同时包含“int”和“float”的列表吗?
  • 在我的情况下,我将有一个列表,该列表将在运行时分配值,类型将在运行时决定。列表中只有一种类型,而不是多种类型...得到答案来自马克..谢谢

标签: c# serialization protocol-buffers protobuf-net


【解决方案1】:

我强烈建议不要在此处或其他地方使用动态功能。它在 V3 中已被弃用,可能是永久的。看起来您在这里真正想要的是来自struct.protoValue。目前在 protobuf-net 中没有内置支持,但我可能很快就会添加它。至于现在:我可能会建议使用一个类型的数组,具有这些东西作为字段。如果你让布局看起来像Value 那样,就字段编号而言,以后应该可以直接交换。

【讨论】:

    【解决方案2】:

    大部分抄自question about protobuf dynamic array

    documentation for dynamic arrays 状态:

    DynamicType - 与类型一起存储附加类型信息(默认情况下它包括 AssemblyQualifiedName,尽管这可以由用户控制)。这使得序列化弱模型成为可能,即对象用于属性成员,但是目前这仅限于合同类型(不是原语),并且不适用于具有继承的类型(这些限制可能稍后删除)。与 AsReference 一样,它使用非常不同的布局格式

    你有一个原语,因此你不能使用 DynamicType。如您收到的错误消息中所述。

    一种解决方法可能是将要存储的原语包装在具有已定义合同的另一种类型中。

    【讨论】:

    • 我已经通过使用Surrogate解决了这个问题,在stackoverflow中已经提到了。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2013-01-29
    • 1970-01-01
    • 2012-02-27
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-04
    • 2010-10-15
    相关资源
    最近更新 更多