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
、aJ
、J
的某些子类还是I
的某些非J
子类