Вопрос

в ПротоБуф-Нет реализация, что означает ПротоИнклюд Атрибут означает и что он делает?

Пример был бы оценен.

я видел это в этом посте и я не уверен, что он делает.Пример был:

[Serializable,
 ProtoContract,
 ProtoInclude(50, typeof(BeginRequest))]
abstract internal class BaseMessage
{
  [ProtoMember(1)]
  abstract public UInt16 messageType { get; }
}

[Serializable,
 ProtoContract]
internal class BeginRequest : BaseMessage
{
    [ProtoMember(1)]
    public override UInt16 messageType
    {
        get { return 1; }
    }
}

Кроме того, есть ли способ создать такое наследование с помощью прототип инструмент?

Это было полезно?

Решение

Извините, я не хотел это пропустить - увы, я не все вижу.

Учитывая специфику вопроса, я предполагаю, что вы хотя бы поверхностно знакомы с .proto;поправьте меня, если я ошибаюсь.

[ProtoInclude] работает очень похоже [XmlInclude] для XmlSerializer - или [KnownType] для DataContractSerializer - это позволяет распознавать подклассы типа во время (де)сериализации.Единственным дополнительным моментом является то, что для идентификации каждого подтипа требуется тег (номер) (который должен быть уникальным и не конфликтовать ни с одним из полей родительского типа).

Протоген:неа;базовая спецификация (от Google) не предусматривает наследование совсем, поэтому у protogen (через .proto) нет механизма для выражения этого.protobuf-net обеспечивает поддержку наследования как расширение, но делает это таким образом, чтобы сообщения оставались совместимыми с другими реализациями.В толчке, может быть Я мог бы добавить поддержку протогена через новые свойства расширения в спецификации Google, но я еще этого не сделал.

Так;посмотреть пример;который выражает отношения наследования между BaseMessage и BeginRequest;независимо от того, делаете ли вы:

Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
  • в любом случае, он начнется с базы (BaseMessage) и работайте вверх;что не так точно правда - пишет данные начиная с BeginRequest (чтобы он знал, что у нас есть BeginRequest как можно раньше во время десериализации).Важно то, что поля из любых родительских типов контрактов включены, и сериализатор просматривает действительный переданный объект, а не только тот тип, который вы сказать это.

Аналогично, при десерилизации, независимо от того, используете ли вы:

Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)

вы получите тип, который вы действительно сериализовали (предположительно, BeginRequest).

Под капотом, в целях совместимости (со спецификацией буферов широкого протокола), это похоже на запись чего-то вроде (простите за ошибки, мой .proto заржавел):

message BaseMessage {
    optional BeginRequest beginRequest = 50;
    optional uint32 messageType = 1;   
}
message BeginRequest {        
}

(переопределение, вероятно, не должно указывать [ProtoMember], кстати.

Обычно он записывает поля в порядке возрастания тегов, но для обеспечения эффективной десериализации движок нахально предпочитает записывать данные подкласса. первый (что явно разрешено спецификацией), т.е.он пишет что-то вроде (вам придется представить двоичный файл...):

[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]

(в этом случае тело подсообщения пустое)

Это покрывает это?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top