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

Ste*_*nds 5 c# inheritance protobuf-net

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

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

这个问题和其他几个问题并没有真正描述如何选择场数,事实上我已经看到了许多不同的变化: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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 5

除了以下内容之外没有要求:

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

除此之外:没关系.留下间隙可能会更容易将其他字段添加到父类型而不会意外地产生冲突,但是:较小的字段数序列化更便宜,因此如果可能:更喜欢小数字