Protobuf net 最简单的protobuf网络示例4需要帮助 [DataContract] 公共一级 { [数据成员(顺序=1)] 公共TId Id{get;set;} } [数据合同] 公共课J:I { [数据成员(顺序=1)] 公共字符串说明{get;set;} } 班级计划 { 静态void Main() { var o=newj{Id=5,Description=“xa-xa”,}; 使用(var ms=new MemoryStream()) { Serializer.Serialize(ms,o); ms.Position=0; var o2=序列化程序。反序列化(ms); Assert(o.Id==o2.Id); } } }

Protobuf net 最简单的protobuf网络示例4需要帮助 [DataContract] 公共一级 { [数据成员(顺序=1)] 公共TId Id{get;set;} } [数据合同] 公共课J:I { [数据成员(顺序=1)] 公共字符串说明{get;set;} } 班级计划 { 静态void Main() { var o=newj{Id=5,Description=“xa-xa”,}; 使用(var ms=new MemoryStream()) { Serializer.Serialize(ms,o); ms.Position=0; var o2=序列化程序。反序列化(ms); Assert(o.Id==o2.Id); } } },protobuf-net,Protobuf Net,为什么断言失败以及如何修复它 谢谢。它失败了,因为protobuf net无法处理继承,除非您通过属性或运行时类型模型为它提供更多线索-本质上它需要从某处(即您)获取字段号。我愿意承认,在这种情况下,跟踪警告可能很有用,因为很明显,这种继承场景可能不仅仅是J 以下添加(在运行时)修复了它: [DataContract] public class I<TId> { [DataMember(Order = 1)] public TId Id { get; se

为什么断言失败以及如何修复它


谢谢。

它失败了,因为protobuf net无法处理继承,除非您通过属性或运行时类型模型为它提供更多线索-本质上它需要从某处(即您)获取字段号。我愿意承认,在这种情况下,跟踪警告可能很有用,因为很明显,这种继承场景可能不仅仅是
J

以下添加(在运行时)修复了它:

  [DataContract]
  public class I<TId>
  {
    [DataMember(Order = 1)]
    public TId Id { get; set; }
  }

  [DataContract]
  public class J : I<int>
  {
    [DataMember(Order = 1)]
    public string Description { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var o = new J { Id = 5, Description = "xa-xa", };
      using (var ms = new MemoryStream())
      {
        Serializer.Serialize(ms, o);
        ms.Position = 0;
        var o2 = Serializer.Deserialize<J>(ms);
        Debug.Assert(o.Id == o2.Id);
      }
    }
  }
RuntimeTypeModel.Default.Add(typeof(I),true).AddSubType(2,typeof(J));

2
的唯一意义在于它不会与为
I
定义的任何其他字段冲突。)

它失败了,因为protobuf net无法处理继承,除非您通过属性或运行时类型模型给它更多的线索-本质上它需要从某处(即您)获取字段号。我愿意承认,在这种情况下,跟踪警告可能很有用,因为很明显,这种继承场景可能不仅仅是
J

以下添加(在运行时)修复了它:

  [DataContract]
  public class I<TId>
  {
    [DataMember(Order = 1)]
    public TId Id { get; set; }
  }

  [DataContract]
  public class J : I<int>
  {
    [DataMember(Order = 1)]
    public string Description { get; set; }
  }

  class Program
  {
    static void Main()
    {
      var o = new J { Id = 5, Description = "xa-xa", };
      using (var ms = new MemoryStream())
      {
        Serializer.Serialize(ms, o);
        ms.Position = 0;
        var o2 = Serializer.Deserialize<J>(ms);
        Debug.Assert(o.Id == o2.Id);
      }
    }
  }
RuntimeTypeModel.Default.Add(typeof(I),true).AddSubType(2,typeof(J));

2
的唯一意义在于它不会与为
I
定义的任何其他字段冲突。)

为什么需要消除歧义?我理解它的必要性,当被序列化对象的静态类型是基本类型之一时,在这种情况下,反序列化器必须知道实例化哪个派生类型。但是在这里,反序列化的类型是明确的,不是吗?@mark重点不在于知道,而在于非常重要的字段号。字段号在protobuf(谷歌规范)中占据主导地位。我在这里使用它们是“实际类型是什么”解析的一部分-它是
I
、是
J
、是
J
的某个子类还是
I
的某个非
J
子类,为什么需要消除歧义?我理解它的必要性,当被序列化对象的静态类型是基本类型之一时,在这种情况下,反序列化器必须知道实例化哪个派生类型。但是在这里,反序列化的类型是明确的,不是吗?@mark重点不在于知道,而在于非常重要的字段号。字段号在protobuf(谷歌规范)中占据主导地位。我在这里使用它们是“实际类型”解析的一部分-它是
I
、a
J
J
的某些子类还是
I
的某些非
J
子类