Вопросы касательно ProtoBuf-Net с наследованием? - PullRequest
1 голос
/ 11 июля 2019

Я хочу использовать protobuf для протокола через сокетное соединение.

Мои вопросы касаются наследования.

Скажите, что в моем проекте есть следующие классы:

  1. Животное
  2. Кошка (наследуется от Животного)
  3. Собака (наследуется от Животного)

Допустим,

  1. Animal наследует от Creature, принадлежащего классу в DLL, для которого я не могу изменить код (допустим, это сторонняя библиотека).
  2. Cat имеет 10 полей, которым я даю атрибуты ProtoMember от 1 до 10 для.
  3. Собака как 12 полей, поэтому я даю этот ProtoMember с 1 по 12.
  4. Животное имеет 5 полей, поэтому я даю этот ProtoMember с 1 по 5.

Покатак хорошо.

Чтобы справиться с наследованием, допустим, я использую следующий атрибут для Cat:

[ProtoInclude(11, typeof(Pet))]

А для Dog я использую:

[ProtoInclude(13, typeof(Pet))]

И об использовании животных:

[ProtoInclude(6, typeof(Creature))]

Вопросы:

  1. Являются ли эти числа, которые я использовал до сих пор, действительными?Если нет, то какими они должны быть и в чем причина?
  2. Должен ли я дать числам в ProtoInclude пробел (например, 111, 113 и 106), чтобы он позволял добавлять новые поля к темклассы?Или я оставлю серию чисел компактной и скорректирую ее в будущем по мере необходимости?

Поэтому, чтобы справиться с наследованием Существа (какой код отсутствует в моем проекте), я считаю, что мне нужно использоватьОбъявление типа времени выполнения (как упомянуто здесь: наследование protobuf-net )

Я не совсем уверен, какие операторы мне понадобятся для этого примера, а также где эти операторы должны быть помещены вмой проект?

Любая помощь будет принята с благодарностью.Спасибо.

1 Ответ

0 голосов
/ 11 июля 2019

[ProtoInclude] работает от базового класса до подкласса - вам нужно аннотировать тип base - так: Pet, что необходимо для объявления [ProtoInclude(...)] маркеров для Cat и Dog. Точно так же Creature должен будет объявить, что ожидает Animal. Очевидно, это проблема, если вы не управляете Creature, но этот можно настроить через RuntimeTypeModel во время выполнения, если это проблема. Лично я бы не рекомендовал использовать тип, которым вы не управляете в иерархии сериализации.

Но на ваши вопросы:

  1. это не имеет значения, если только оно не конфликтует с другими числами объявленного типа; ниже - дешевле (12 дешевле кодировать, чем 34134923)
  2. полностью зависит от вас; не имеет значения, чередуются ли обычные поля и поля подтипов, поэтому наличие
[ProtoInclude(4, Whatever)]
[ProtoInclude(7, WhateverElse)]
class Foo {
   [ProtoMember(1, ...)] ...
   [ProtoMember(2, ...)] ...
   [ProtoMember(3, ...)] ...
   [ProtoMember(5, ...)] ...
   [ProtoMember(6, ...)] ...
   [ProtoMember(8, ...)] ...
}

но я признаю, что многие люди предпочитают разделять 2 - возможно,

[ProtoInclude(101, Whatever)]
[ProtoInclude(102, WhateverElse)]
class Foo {
   [ProtoMember(1, ...)] ...
   [ProtoMember(2, ...)] ...
   [ProtoMember(3, ...)] ...
   [ProtoMember(4, ...)] ...
   [ProtoMember(5, ...)] ...
   [ProtoMember(6, ...)] ...
}
...