Protobuf .NET继承类的序列化 [英] Protobuf .NET serialization for inheritance classes

查看:120
本文介绍了Protobuf .NET继承类的序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将代码序列化程序从NetDataContract迁移到Protobuf.Net.

I'm trying to migrate my code serializer from NetDataContract to Protobuf.Net.

让我们考虑以下课程示例以帮助理解:

Let's consider the following class example to help the understanding:

[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,我使用以下选项:

To be able to use Protobuf .NET using DataContract, I'm using the following options:

RuntimeTypeModel.Default.InferTagFromNameDefault = true;            
RuntimeTypeModel.Default.AutoAddProtoContractTypesOnly = false;

使用这些选项,上面显示的示例的序列化可以工作,但是当添加它的继承时,复杂性会增加.让我们通过此类改进我们的示例:

Using those options, the serialization of the example showed above works, but when adding an inheritance of it, the complexity grows. Let's improve our example with this class:

[DataContract(Name = "b", IsReference = true)]
class InheritanceTest : Test
{
    [DataMember(Name = "c")]
    public string Text { get; set; }
}

现在,要能够序列化从"Test"继承的类"InheritanceTest",我必须添加ProtoInclude参数(已经尝试仅使用KnownType,但它不起作用).类测试"的属性应如下所示:

Now, to be able to serialize the class "InheritanceTest" that inherits from "Test", I must add the ProtoInclude parameter (already tried to use only the KnownType but it didn't work). Class "Test" attributes should be like that:

[DataContract(Name "a", IsReference = true)]
[KnownType(typeof(InheritanceTest)]
[ProtoInclude(<TAG>, typeof(InheritanceTest)]
class Test { ... }

复杂度恕我直言,这是当您必须使用自动从成员(DataMembers)自动分配的顺序中未自动使用的数字来填充"TAG"时.在此示例中,如果我使用TAG = 1,则会出现错误,因为属性ID已使用它. TAG = 2和属性名称相同.所以我需要至少放3个.

The complexity IMHO is when you have to fill the "TAG" with a number that is not automatically used from the members (DataMembers) auto-assigned order. In this example, if I use TAG=1 it gets error because property Id already uses it. The same with TAG=2 and property Name. So I need to put at least 3.

这没关系,因为此类太简单了,但是当该类具有多个属性时该怎么办?而且,每当我向其添加属性时,都应该更改TAG吗?似乎维护很糟糕.

That's okay as this class is too simple, but what should I do when the class has several properties? And should I change the TAG whenever I add a property to it? Seems terrible for maintenance.

我该如何以更简单的方式做到这一点?我想念什么吗?

How can I do it in a simpler way? Am I missing something?

考虑到它是自动分配的,应该只进行一次并缓存.更好的是,应该在编译时完成.

Considering it is automatically assigned, it should be done only once and cached. Even better, it should be done in compile time.

此外...为什么我不能使用[KnownType]属性,而序列化程序却根据定义的类类型的DataContract的名称自动分配TAG?请注意,使用名称自动分配订单的DataMember也会发生类似的情况.

Additionally... why can't I use [KnownType] Attribute and the serializer auto-assigns the TAG based on the Name of the DataContract of the class type defined? Note that something similar happens with DataMember using the Name to auto-assign Order.

推荐答案

,但是当添加它的继承时,复杂度会增加.

but when adding an inheritance of it, the complexity grows.

是的.

添加属性后,是否应该更改TAG?

And should I change the TAG whenever I add a property to it?

您应该从不更改标签.曾经.

You should never change a tag. Ever.

维护似乎很糟糕.

Seems terrible for maintenance.

完全正确.

考虑到它是自动分配的,应该只进行一次并缓存.

Considering it is automatically assigned, it should be done only once and cached.

是在运行时.

更好的是,它应该在编译时完成.

Even better, it should be done in compile time.

好吧,我不是在关注推断"方面,而是一般,这是我与编译器团队正在进行的讨论.

Well, I'm not focusing on the "infer" aspects, but in general that is an ongoing discussion I'm having with the compiler team.

我想念什么吗?

Am I missing something?

我是这样认为的;尤其是,永远将要更改的模型上,您不应使用按名称推断"选项.添加该选项是为了在现有的固定模型上使事情正常工作的务实方式,但是它非常脆弱-在许多方面都非常危险.关于您的理解,应该出现 警告,但坦率地说,推荐选项是:始终明确.将[ProtoMember(42)](或其他内容)添加到每个属性.这样就不用猜测了,也没有增加破坏成员的新成员的风险.您可以看到所有内容,也可以了解所有内容.

I think so, yes; in particular, you should not be using "infer by name" options on models that are ever going to change. That option was added as a pragmatic way to just make things work on existing fixed models, but it is very brittle - and in many ways dangerous. There should be warnings that appear in your intellisense about this, but frankly the recommended option is: always be explicit. Add [ProtoMember(42)] (or whatever) to each property. Then there's no guessing, and no risk of adding new members that break things. You can see everything, and you can understand everything.

这篇关于Protobuf .NET继承类的序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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