Frage

In der protobuf-Net Implementierung, was hält die ProtoInclude Attribut bedeuten, und was tun sie?

Ein Beispiel würde geschätzt.

Ich sah es in diesem Beitrag und ich bin nicht sicher, was es tut. Das Beispiel war:

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

Auch ist es eine Möglichkeit, solche Vererbung mit dem Protogen Werkzeug zu generieren?

War es hilfreich?

Lösung

Sorry, ich habe nicht vor, diese zu verpassen -. Ach, ich sehe alles nicht

die Besonderheiten in der Frage gegeben, ich gehe davon aus, dass Sie mit .proto mindestens passingly vertraut sind; korrigieren Sie mich, wenn ich falsch bin.

[ProtoInclude] arbeitet viel wie [XmlInclude] für XmlSerializer - oder [KnownType] für DataContractSerializer - sie erlaubt es Subklassen eines Typs während (de) Serialisierung zu erkennen. Die einzige zusätzliche Sache ist, dass es einen Tag (Zahl) muss jeden Untertyp zu identifizieren (die eindeutig sein muss, und nicht mit einem der Feldern aus dem übergeordneten Typ kollidieren).

Re Protogen: nein; die zugrunde liegende Spezifikation (von Google) macht für die Vererbung keine Bestimmung an alle , so Protogen (via .proto) diese keinen Mechanismus zum Ausdruck bringen hat. protobuf-net bietet Vererbungs Unterstützung als Erweiterung , aber tut es in einer Weise, dass die Nachrichten draht kompatibel mit den anderen Implementierungen noch verlässt. Bei einem Push, vielleicht konnte ich Protogen Unterstützung über die neuen Erweiterungseigenschaften in dem Google-spec hinzufügen, aber ich habe das noch nicht getan.

So; am Beispiel zu sehen; dass zum Ausdruck bringt eine Vererbungsbeziehung zwischen BaseMessage und BeginRequest; unabhängig davon, ob Sie tun:

Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
  • oder so, wird es an der Basis (BaseMessage) und arbeiten beginnen nach oben; Das ist nicht genau wahr - es schreibt die Daten mit BeginRequest beginnen (so dass es weiß, haben wir eine BeginRequest so früh wie möglich bei der Deserialisierung). Das Wichtigste ist, dass die Felder von jedem Elternteil Vertragsarten enthalten ist, und der Serializer schaut auf die eigentlichen Objekt übergeben -. Nicht nur der Typ, den Sie sagen ist

Auch während deserilaization, unabhängig davon, ob Sie:

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

finden Sie die Art erhalten Sie tatsächlich serialisiert (vermutlich ein BeginRequest).

Unter der Haube aus Kompatibilitätsgründen (mit der breiten Protokollpuffer-Spezifikation), das ist ähnlich wie etwas zu schreiben (verzeihen Fehler, mein .proto ist rostig):

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

(die Überschreibung sollte wahrscheinlich nicht [ProtoMember] angeben, btw.

Normalerweise würde es Felder in aufsteigendem Tag, um schreiben, aber für effizienter zu machen Deserialisierung des Motor der Unterklassen Daten schreiben cheekily wählt zuerst (die explizit von der Spezifikation erlaubt ist) - dh, es schreibt so etwas wie (Sie werden das binäre vorzustellen haben ...):

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

(in diesem Fall der Körper der Unter Nachricht ist leer)

Ist, dass sie decken?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top