У меня есть конкретный прецедент для наследования с использованием protobuf-net, который я еще не нашел, хотя здесь все еще включен (хотя он с удовольствием перенаправляется на любые ответы, которые были бы полезны) ,protobuf-net: deserialise extend ключевое слово в иерархию наследования
Я должен десериализовать некоторые объекты из стороннего протокола protobuf (GTFS-RT), а поставляемое .proto использует ключевое слово extend
для расширения базовых типов (которые мы также используем с другими каналами), что кажется разумным с объективной точки зрения. Однако я не могу заставить protobuf-net десериализовать каналы в этом формате в соответствующую иерархию наследования.
Например, базовая .proto определяет FeedHeader
(под названием пакета transit_realtime
):
message FeedHeader {
required string gtfs_realtime_version = 1;
enum Incrementality {
FULL_DATASET = 0;
DIFFERENTIAL = 1;
}
optional Incrementality incrementality = 2 [default = FULL_DATASET];
optional uint64 timestamp = 3;
extensions 1000 to 1999;
}
Сторонний расширяет FeedHeader
включить еще одно свойство:
extend transit_realtime.FeedHeader {
optional NyctFeedHeader nyct_feed_header = 1001;
}
Я хотел бы для десериализации этого в следующую иерархию классов:
namespace Base.GTFS
{
[ProtoContract(Name = nameof(FeedHeader))]
public class FeedHeader
{
[ProtoMember(1, IsRequired = true, Name = nameof(gtfs_realtime_version), DataFormat = DataFormat.Default)]
public string gtfs_realtime_version { get; set; }
[ProtoMember(2, IsRequired = false, Name = nameof(incrementality), DataFormat = DataFormat.TwosComplement)]
[DefaultValue(Incrementality.FULL_DATASET)]
public Incrementality incrementality { get; set; } = Incrementality.FULL_DATASET;
[ProtoMember(3, IsRequired = false, Name = nameof(timestamp), DataFormat = DataFormat.TwosComplement)]
[DefaultValue(default(ulong))]
public ulong timestamp { get; set; } = default(ulong);
public FeedHeader() { }
#region Nested Enums
[ProtoContract(Name = nameof(Incrementality))]
public enum Incrementality
{
[ProtoEnum(Name = nameof(FULL_DATASET), Value = 0)]
FULL_DATASET = 0,
[ProtoEnum(Name = nameof(DIFFERENTIAL), Value = 1)]
DIFFERENTIAL = 1
}
#endregion
}
}
namespace Other.GTFS
{
[ProtoContract(Name = nameof(FeedHeader))]
public class FeedHeader : Base.GTFS.FeedHeader
{
/// <summary>
/// NYCT Subway extensions for the feed header
/// </summary>
[ProtoMember(1001, Name = nameof(nyct_feed_header), IsRequired = false, DataFormat = DataFormat.Default)]
public NyctFeedHeader nyct_feed_header { get; set; } = null;
public FeedHeader() : base() { }
}
}
Прочитав другие сообщения здесь и в другом месте, я попытался использовать методы AddSubType
и методы AddSurrogate
, но обнаружил, что я могу только надежно иметь все десериализованные поля, если я переопределяю все поля в базовом классе. Это кажется крайне неэффективным и будет ломаться, если (и когда) меняются базовые типы. Нам также нужно использовать сериализацию для базовых типов для других каналов, поэтому мне нужно решение, которое будет легко расширяться.
Кто-нибудь знает какой-либо способ поддержать этот сценарий или какие-либо предложения, которые могут вам помочь?
Спасибо за информацию - я понял, что это почти так, как это работает. Это позор, так как у меня есть сервисный уровень, который находится поверх них, который объявляет интерфейс, который использует базовые классы - я думаю, мне нужно будет извлечь необходимые части базовой модели в интерфейсы и обеспечить их применение к частичным сгенерированным классам (упрощается наблюдение, поскольку они являются частичными). – davide