Pregunta

En el protobuf-Net aplicación , lo que hace el ProtoInclude atribuir significa, y lo que hace?

Un ejemplo sería apreciada.

en este post y no estoy seguro de lo lo hace. El ejemplo fue:

[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; }
    }
}

Además, ¿hay una manera de generar tales herencia mediante el Protogen herramienta?

¿Fue útil?

Solución

Lo siento, no fue mi intención faltar éste -. Por desgracia, no lo veo todo

Teniendo en cuenta las características específicas de la pregunta, voy a asumir que son al menos de pasada familiarizado con .proto; corrígeme si estoy equivocado.

[ProtoInclude] funciona muy parecido a [XmlInclude] para XmlSerializer - o [KnownType] para DataContractSerializer - que le permite reconocer las subclases de un tipo en (de) la serialización. La única cosa adicional es que se necesita una etiqueta (número) para identificar cada subtipo (que debe ser único, y no entrar en conflicto con cualquiera de los campos de tipo matriz).

Re Protogen: nope; la especificación subyacente (por Google) no prevé la herencia en absoluto , por lo Protogen (a través de .proto) no tiene ningún mecanismo para expresar esto. protobuf-net ofrece soporte de herencia como un extensión , pero lo hace de una manera que todavía deja los mensajes de cable compatible con las otras implementaciones. En un impulso, tal vez Me podría añadir soporte Protogen a través de las nuevas propiedades de extensión en la especificación de Google, pero no lo han hecho todavía.

Por lo tanto; mirar el ejemplo; que expresa una relación de herencia entre BaseMessage y BeginRequest; independientemente de si lo haces:

Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
  • cualquier manera, se iniciará en la base (BaseMessage) y trabajar hacia arriba; que no es exactamente cierto - escribe los datos de a partir de BeginRequest (para que sepa que tenemos un BeginRequest tan pronto como sea posible durante la deserialización). Lo importante es que los campos de cualquier tipo de contrato de los padres está incluido, y el serializador se ve en la real objeto pasado en -. No sólo el tipo que decir es

Asimismo, durante deserilaization, independientemente de si utiliza:

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

obtendrá el tipo que realmente serializado (presumiblemente un BeginRequest).

Bajo el capó, por motivos de compatibilidad (con la amplia especificación de búferes de protocolo), esto es similar a escribir algo así como (valga cualquier error, mi .proto es oxidado):

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

(la anulación probablemente no debería especificar [ProtoMember], por cierto.

Normalmente, se escribiría campos en orden etiqueta ascendente, pero para hacer para una eficiente deserialización el motor descaradamente elige para escribir los datos de subclase primero (que está explícitamente permitido por la especificación) - es decir, se escribe algo así como (que tendrá que imaginar el binario ...):

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

(en este caso, el cuerpo de la sub-mensaje está vacío)

¿Eso lo cubren?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top