Domanda

protobuf-Net implementazione , che cosa fa il ProtoInclude di attributo media, e che cosa fa?

Un esempio sarebbe apprezzato.

L'ho visto in questo post e io non sono sicuro di quello che lo fa. L'esempio è stato:

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

Inoltre, c'è un modo per generare tale eredità con il ProtoGen strumento?

È stato utile?

Soluzione

Mi dispiace, non volevo mancare a questo uno -. Ahimè, non vedo tutto

Data la specificità della domanda, ho intenzione di pensare che vi sono almeno passingly familiarità con Proto; correggetemi se sbaglio.

[ProtoInclude] funziona un po 'come [XmlInclude] per XmlSerializer - o [KnownType] per DataContractSerializer - permette di riconoscere sottoclassi di tipo durante la (de) serializzazione. L'unica cosa aggiuntiva è che ha bisogno di un tag (numero) per identificare ciascun sottotipo (che deve essere unico, e non scontrarsi con nessuno dei campi dal tipo di genitore).

Re ProtoGen: no; le specifiche di base (da Google) non prevede per l'eredità a tutti , in modo ProtoGen (via Proto) non ha alcun meccanismo per esprimere questo. protobuf-net fornisce supporto ereditarietà come estensione , ma fa in modo che lascia ancora i messaggi wire-compatibile con le altre implementazioni. Nel corso di una spinta, forse ho potuto aggiungere il supporto ProtoGen tramite le nuove proprietà di estensione nelle specifiche di Google, ma non ho ancora fatto.

; a guardare l'esempio; che esprime una relazione di ereditarietà tra BaseMessage e BeginRequest; indipendentemente dal fatto che si fa:

Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
  • in entrambi i casi, si avvia alla base (BaseMessage) e lavorare verso l'alto; che non è esattamente vero - scrive dati a partire BeginRequest (in modo che sa che abbiamo un BeginRequest il più presto possibile durante la deserializzazione). La cosa importante è che i campi da qualsiasi tipo di contratto genitore è incluso, e il serializzatore guarda il reale oggetto passato in -. Non solo il tipo di dire è

Allo stesso modo, durante deserilaization, indipendentemente dal fatto che si utilizza:

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

otterrete il tipo che in realtà serializzato (presumibilmente un BeginRequest).

Sotto il cofano, per ragioni di compatibilità (con la specifica di protocollo buffer di larghezza), questo è simile a scrivere qualcosa di simile (perdonare eventuali errori, il mio Proto è arrugginito):

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

(l'override probabilmente non dovrebbe specificare [ProtoMember], btw.

Normalmente, scriverebbe campi in ordine tag ascendente, ma per rendere per un efficiente deserializzazione il motore sceglie sfacciatamente per scrivere i dati della sottoclasse prima (che è esplicitamente consentito dalle specifiche) - vale a dire che scrive qualcosa di simile (si dovrà immaginare il binario ...):

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

(in questo caso, il corpo del messaggio secondario è vuoto)

Non che coprono esso?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top