使用protobuf-net继承时如何选择字段编号?

时间:2015-03-26 14:36:43

标签: c# inheritance protobuf-net

我使用protobuf-net序列化了许多类型,其中一些类型是从基类型继承而来的。我知道Protocol Buffers规范不支持继承,并且protobuf-net中的支持基本上是一种解决方法,因为它。

我正在配置自定义RuntimeTypeModel,并使用AddAddSubType方法,而不是使用protobuf-net属性。我不太了解的是我应该如何确定使用哪个数字来传递给AddSubType方法的字段数字(也就是ProtoInclude中使用的数字1}}属性)。

This SO question以及其他几个类似的人并没有真正描述如何选择字段编号,而且我确实看到了许多不同的变体:4& 5; 7& 8; 101& 102& 103; 20; 500;显然他们被选中以免互相冲突,但是他们是如何选择的?什么决定从哪个数字开始?

以下代码是一个人为的示例,但它确实与我的heirarchy(具有两个派生子类型的基础Event类型)匹配。

using System;
using System.Collections.Generic;
using ProtoBuf.Meta;

namespace Test
{
    public sealed class History
    {
        public History()
        {
            Events = new List<Event>();
        }

        public ICollection<Event> Events { get; private set; }
    }

    public enum EventType
    {
        ConcertStarted, ConcertFinished, SongPlayed
    }

    public class Event
    {
        public EventType Type { get; set; }
        public DateTimeOffset Timestamp { get; set; }
    }

    public sealed class Concert : Event
    {
        public string Location { get; set; }
    }

    public sealed class Song : Event
    {
        public string Name { get; set; }
    }

    public static class ModelFactory
    {
        public static RuntimeTypeModel CreateModel()
        {
            RuntimeTypeModel model = TypeModel.Create();
            model.Add(typeof(DateTimeOffset), applyDefaultBehaviour: false)
                .SetSurrogate(typeof(DateTimeOffsetSurrogate));
            model.Add(typeof(History), applyDefaultBehaviour: false)
                .Add("Events");
            model.Add(typeof(Concert), applyDefaultBehaviour: false)
                .Add("Location");
            model.Add(typeof(Song), applyDefaultBehaviour: false)
                .Add("Name");
            model.Add(typeof(Event), applyDefaultBehaviour: false)
                .Add("Type", "Timestamp")
                .AddSubType(???, typeof(Concert))
                .AddSubType(???, typeof(Song));
            return model;
        }
    }
}

1 个答案:

答案 0 :(得分:5)

除了以下之外没有其他要求:

  • 他们必须是正整数
  • 他们不能发生冲突
  • 它们必须是可靠的可重复的(无论您重启应用程序多少次,重要的是子类型和数字匹配,即使您添加其他类型等也是如此)

除此之外:它并不重要。留下空隙可能会更容易将其他字段添加到父类型而不会意外地产生冲突,但是:较小的字段数序列化更便宜,所以如果可能:更喜欢小数字