Буферы протоколов Наследование .NET

У меня есть данные в формате Protocol Buffers, которые можно описать следующим образом

message Sections {
    repeated Section sections = 1;
}

message Section {
    required uint32 type = 1;
    required bytes payload = 2;
}

message SectionType1 {
    required int32 fieldType1 = 1;
    // ...
}

message SectionType2 {
    required int32 fieldType2 = 1;
    // ...
}

message SectionType3 {
    required int32 fieldType3 = 1;
    // ...
}

Я использую библиотеку protobuf-net (+ protogen + precompile). Как мне десериализовать такие данные в DTO, подобные

public class Sections
{
    public List<Section> Sections { get; }
}

public abstract class Section
{
}

public class SectionType1 : Section
{
    public int FieldType1 { get; }
}

public class SectionType2 : Section
{
    public int FieldType2 { get; }
}

public class SectionType3 : Section
{
    public int FieldType3 { get; }
}

Можно ли работать с такими данными из .NET (используя прекомпиляцию, т.к. я на лайт фреймворке)?


person A-student    schedule 21.11.2012    source источник
comment
Буферы протоколов предназначены для сериализации информации — простым и последовательным способом. Вы должны рассматривать любые типы, которые вы используете в подобных вещах, как формы, которые просто содержат данные, без наследования или поведения. См. Объекты передачи данных.   -  person Peter Ritchie    schedule 13.09.2014


Ответы (2)


Для этого вам придется сделать это вручную, т.е.

[ProtoContract]
public abstract class Section
{
    [ProtoMember(1)] public int Type {get;set;}
    [ProtoMember(2)] public byte[] Payload {get;set;}
}

а остальное обрабатывать вручную. карты наследования protobuf-net покрывают следующую схему .proto:

message Section {
    optional SectionType1 Type1 = 1;
    optional SectionType2 Type2 = 2;
    optional SectionType3 Type3 = 3;
}

где у нас есть, скажем:

[ProtoInclude(1, typeof(SectionType1)]
[ProtoInclude(2, typeof(SectionType2)]
[ProtoInclude(3, typeof(SectionType3)]
public abstract class Section
{
}
person Marc Gravell    schedule 21.11.2012

Просто хотел добавить свои выводы, я создал файл .proto, который имеет один базовый класс и 20 производных классов. Я сгенерировал код через protobuf-net r668\ProtoGen. Я выполнил шаги, перечисленные выше, но я все еще получаю сообщение об ошибке, подтип не найден.

Просто путем проб и ошибок я увидел, что сгенерированный код имеет значение global::ProtoBuf.IExtensible для всех сгенерированных классов, я удалил это плюс ниже 3 строк из всех сгенерированных классов private global::ProtoBuf.IExtension extensionObject; global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) { return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); }

После этого ошибка не появлялась. Я не знаю, почему это помогло, но это сработало.

person Rajesh Gaur    schedule 13.09.2014