我正在尝试将我的代码序列化程序从 NetDataContract 迁移到 Protobuf.Net。
让我们考虑以下类示例来帮助理解:
[DataContract(Name "a", IsReference = true)]
class Test
{
[DataMember(Name = "a")]
public int Id { get; set; }
[DataMember(Name = "b")]
public string Name { get; set; }
}
为了能够通过 DataContract 使用 Protobuf .NET,我使用了以下选项:
RuntimeTypeModel.Default.InferTagFromNameDefault = true;
RuntimeTypeModel.Default.AutoAddProtoContractTypesOnly = false;
使用这些选项,上面显示的示例的序列化可以工作,但是当添加它的继承时,复杂性会增加。让我们用这个类改进我们的例子:
[DataContract(Name = "b", IsReference = true)]
class InheritanceTest : Test
{
[DataMember(Name = "c")]
public string Text { get; set; }
}
现在,为了能够序列化从“Test”继承的类“InheritanceTest”,我必须添加 ProtoInclude 参数(已经尝试仅使用 KnownType 但它不起作用)。类“测试”属性应该是这样的:
[DataContract(Name "a", IsReference = true)]
[KnownType(typeof(InheritanceTest)]
[ProtoInclude(<TAG>, typeof(InheritanceTest)]
class Test { ... }
恕我直言,复杂性在于您必须使用成员(DataMembers)自动分配的订单中未自动使用的数字填充“标签”。在此示例中,如果我使用 TAG=1 则会出错,因为属性 Id 已经使用它。与 TAG=2 和属性名称相同。所以我至少需要放3个。
没关系,因为这个类太简单了,但是当这个类有几个属性时我该怎么办?每当我向其添加属性时,我是否应该更改 TAG?维护起来似乎很糟糕。
我怎样才能以更简单的方式做到这一点?我错过了什么吗?
考虑到它是自动分配的,它应该只执行一次并缓存。更好的是,它应该在编译时完成。
另外...为什么我不能使用 [KnownType] 属性,并且序列化程序会根据定义的类类型的 DataContract 的名称自动分配 TAG?请注意,使用 Name 自动分配 Order 的 DataMember 也会发生类似的情况。