【问题标题】:Subtype fieldnumber order dependent in protobuf-net子类型字段编号顺序依赖于 protobuf-net
【发布时间】:2013-02-26 06:19:06
【问题描述】:

我可以看到 protobuf-net 似乎需要对运行类型模型进行确定性排序。什么是一个很好的策略来使用而不需要在每个类上都有属性来进行排序。

如果您是通过属性来实现,protobuf 它自己会如何做?

model.Add(typeof(IMessage), false).AddSubType(8500, typeof(DogBarkedEvent));
model.Add(typeof(IMessage), false).AddSubType(8501, typeof(DogBarkedEvent2));

如果我创建一个新模型并尝试反序列化

model2.Add(typeof(IMessage), false).AddSubType(8655, typeof(DogBarkedEvent));
model2.Add(typeof(IMessage), false).AddSubType(5300, typeof(DogBarkedEvent2));

肯定会失败。

我不知道运行时会有多少子类型,所以我担心下次启动应用程序时顺序可能会改变。

我已经阅读过这篇之前的帖子protobuf-net v2 type meta,虽然没有说明如何生成有关唯一标识符的好方法。

【问题讨论】:

    标签: .net serialization protobuf-net


    【解决方案1】:

    它不依赖于 order - 它依赖于 value。 prototobuf(意思是:google 定义的规范;不是专门针对 protobuf-net)非常简洁。你得到的只是数字标识符,告诉你你将要得到什么。

    如果我们首先考虑属性/字段(.Name.DateOfBirth 等) - 那么这就是它在(例如)线路上的键 17.Name 属性之间的映射方式。显然如果你在Name 17 时存储数据,然后改变主意,在Name 22ShoeSize 时读回来17,那么会有很大的问题。字段编号映射是合同的重要组成部分;如果您需要读取旧数据,则不应更改字段编号映射(嗯,有一些有限的方法可以解决它,涉及自定义模型和一些技巧......但没什么好玩的)。

    现在;让我们考虑继承。 protobuf 没有定义继承;以任何方式。为了您的方便,protobuf-net 提供了一种使继承工作的机制,通过将继承建模为子对象的封装。这意味着映射DogBarkedEvent 8500 与我们后面的Name / ShoeSize 示例基本没有区别。如果我们改变主意并使用不同的字段编号,它将失败

    所以是的,您需要一种强大的可重复方式来为DogBarkedEvent每次生成相同的密钥,无论添加了多少其他子类 /删除/重命名。 最简单的方法是使用属性,例如[ProtoInclude(...)],因为它在代码中是固定的和静态的。如果这不是可取的,那么建议使用某种地图的外部存储;一个平面文本文件就可以了——只需解析它并应用;即

    My.NameSpace.DogBarkedEvent=8500
    My.NameSpace.DogBarkedEvent2=8501
    

    这也取决于你为什么不想使用[ProtoInclude(...)];如果这是因为生成了你的代码文件,那么考虑partial classes:

    namespace My.NameSpace
    {    
        [ProtoInclude(8500, typeof(DogBarkedEvent))]
        [ProtoInclude(8501, typeof(DogBarkedEvent2))]
        partial class MyParentType {}
    }
    

    如果问题是您不想在代码中使用特定于库的类型;然后可能声明您自己的属性并在配置模型时阅读它;例如:

    [SubtypeKey(8500, typeof(DogBarkedEvent))]
    [SubtypeKey(8501, typeof(DogBarkedEvent2))]
    

    (并使用Attribute.GetCustomAttribute 获取)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-08
      • 2019-03-11
      • 1970-01-01
      • 2016-04-20
      相关资源
      最近更新 更多