Freigeben über


Serialisierung

Hinweis

Dieser Inhalt wird mit Genehmigung von Pearson Education, Inc. aus Framework Design Guidelines: Konventionen, Idiome und Muster für wiederverwendbare .NET-Bibliotheken, 2. Auflage nachgedruckt. Diese Ausgabe wurde 2008 veröffentlicht, und das Buch wurde seitdem in der dritten Ausgabe vollständig überarbeitet. Einige der Informationen auf dieser Seite sind möglicherweise veraltet.

Serialisierung ist der Prozess der Konvertierung eines Objekts in ein Format, das leicht beibehalten oder transportiert werden kann. Sie können z. B. ein Objekt serialisieren, es über das Internet mithilfe von HTTP übertragen und auf dem Zielcomputer deserialisieren.

Das .NET Framework bietet drei haupt serialisierungstechnologien, die für verschiedene Serialisierungsszenarien optimiert sind. In der folgenden Tabelle sind diese Technologien und die wichtigsten Frameworktypen aufgeführt, die sich auf diese Technologien beziehen.

Technologiename Haupttypen Szenarien
Serialisierung des Datenvertrags DataContractAttribute
DataMemberAttribute
DataContractSerializer
NetDataContractSerializer
DataContractJsonSerializer
ISerializable
Allgemeine Persistenz
Webdienste
JSON
XML-Serialisierung XmlSerializer XML-Format mit voller Kontrolle über die Form des XML-Codes
Laufzeitserialisierung (Binary und SOAP) SerializableAttribute
ISerializable
BinaryFormatter
SoapFormatter
.NET-Remotezugriff

✔️ Denken Sie beim Entwerfen neuer Typen an die Serialisierung.

Auswählen der richtigen Serialisierungstechnologie zur Unterstützung

✔️ ERWÄGEN Sie die Unterstützung von Data Contract Serialization, wenn Instanzen Ihres Typs möglicherweise beibehalten oder in Webdiensten verwendet werden müssen.

✔️ Ziehen Sie die Unterstützung der XML-Serialisierung in Betracht, anstelle oder zusätzlich zur Data Contract Serialization, wenn Sie mehr Kontrolle über das XML-Format benötigen, das beim Serialisieren des Typs erzeugt wird.

Dies kann in einigen Interoperabilitätsszenarien erforderlich sein, in denen Sie ein XML-Konstrukt verwenden müssen, das von der Serialisierung des Datenvertrags nicht unterstützt wird, z. B. zum Erstellen von XML-Attributen.

✔️ ERWÄGEN Sie die Unterstützung der Runtime-Serialisierung, wenn Instanzen Ihres Typs über .NET Remoting-Grenzen hinweg reisen müssen.

❌ VERMEIDEN Sie die Unterstützung der Runtime-Serialisierung oder XML-Serialisierung nur aus allgemeinen Persistenzgründen. Bevorzugen Sie stattdessen die Serialisierung des Datenvertrags.

Unterstützung der Datenvertragsserialisierung

Typen können die Datenvertragsserialisierung unterstützen, indem sie DataContractAttribute auf den Typ und DataMemberAttribute auf die Mitglieder (Felder und Eigenschaften) des Typs anwenden.

✔️ ERWÄGEN Sie, die Datenmember des Typs als öffentlich zu kennzeichnen, wenn der Typ bei teilweiser Vertrauenswürdigkeit verwendet werden kann.

In vollem Vertrauen können Datenkontrakt-Serialisierer nicht-öffentliche Typen und Mitglieder serialisieren und deserialisieren, aber nur öffentliche Mitglieder können bei teilweisem Vertrauen serialisiert und deserialisiert werden.

✔️ IMPLEMENTIEREN Sie einen Getter und Setter für alle Eigenschaften, die über DataMemberAttribute verfügen. Datenvertragsserialisierer erfordern sowohl einen Getter als auch einen Setter, damit der Typ als serialisierbar betrachtet wird. (In .NET Framework 3.5 SP1 können einige Sammlungseigenschaften nur „get-only“ sein.) Wenn der Typ nicht bei teilweiser Vertrauenswürdigkeit verwendet wird, können einer oder beide Eigenschaftenaccessoren nicht öffentlich sein.

✔️ ERWÄGEN SIE die Verwendung der Serialisierungsrückrufe für die Initialisierung von deserialisierten Instanzen.

Konstruktoren werden nicht aufgerufen, wenn Objekte deserialisiert werden. (Es gibt Ausnahmen von der Regel. Konstruktoren von Auflistungen, die CollectionDataContractAttribute mit gekennzeichnet sind, werden während der Deserialisierung aufgerufen.) Daher muss jede Logik, die während der normalen Konstruktion ausgeführt wird, als eines der Serialisierungsrückrufe implementiert werden.

OnDeserializedAttribute ist das am häufigsten verwendete Rückrufattribut. Die anderen Attribute in der Familie sind OnDeserializingAttribute, OnSerializingAttributeund OnSerializedAttribute. Sie können verwendet werden, um Rückrufe zu markieren, die vor der Deserialisierung, vor der Serialisierung und schließlich nach der Serialisierung ausgeführt werden.

✔️ ERWÄGEN SIE, KnownTypeAttribute zu verwenden, um konkrete Typen anzugeben, die beim Deserialisieren eines komplexen Objektdiagramms verwendet werden sollen.

✔️ Erwägen Sie die Abwärts- und Vorwärtskompatibilität beim Erstellen oder Ändern serialisierbarer Typen.

Denken Sie daran, dass serialisierte Streams zukünftiger Versionen Ihres Typs in die aktuelle Version deserialisiert werden können und umgekehrt.

Stellen Sie sicher, dass Datenmitglieder, auch privat und intern, ihre Namen, Typen oder sogar ihre Reihenfolge in zukünftigen Versionen des Typs nicht ändern können, es sei denn, besondere Sorgfalt wird unternommen, um den Vertrag mithilfe expliziter Parameter für die Datenvertragsattribute beizubehalten.

Testen Sie die Kompatibilität der Serialisierung, wenn Sie Änderungen an serialisierbaren Typen vornehmen. Versuchen Sie eine Deserialisierung der neuen Version in eine alte Version und umgekehrt.

✔️ ERWÄGEN Sie die Implementierung von IExtensibleDataObject, um wiederholte Umwandlungen zwischen verschiedenen Versionen des Typs zu gestatten.

Die Schnittstelle ermöglicht es dem Serialisierer, sicherzustellen, dass während des Roundtrippings keine Daten verloren gehen. Die IExtensibleDataObject.ExtensionData Eigenschaft wird verwendet, um Daten aus einer zukünftigen Version des Typs zu speichern, die der aktuellen Version unbekannt sind, und daher können sie nicht in den Datenmitgliedern gespeichert werden. Wenn die aktuelle Version anschließend serialisiert und in eine zukünftige Version deserialisiert wird, sind die zusätzlichen Daten im serialisierten Datenstrom verfügbar.

Unterstützen der XML-Serialisierung

Datenkontraktserialisierung ist die wichtigste (Standard-)Serialisierungstechnologie im .NET Framework, aber es gibt Serialisierungsszenarien, die von der Datenkontraktserialisierung nicht unterstützt werden. So erhalten Sie beispielsweise keine vollständige Kontrolle über die Form von XML, die vom Serialisierer erzeugt oder verbraucht wird. Wenn eine solche feiner Kontrolle erforderlich ist, muss die XML-Serialisierung verwendet werden, und Sie müssen Ihre Typen so entwerfen, dass diese Serialisierungstechnologie unterstützt wird.

❌ VERMEIDEN Sie das Entwerfen ihrer Typen speziell für die XML-Serialisierung, es sei denn, Sie haben einen sehr starken Grund, die Form des erstellten XML-Codes zu steuern. Diese Serialisierungstechnologie wurde durch die im vorherigen Abschnitt erläuterte Serialisierung des Datenvertrags abgelöst.

✔️ ERWÄGEN Sie die Implementierung der IXmlSerializable Schnittstelle, wenn Sie noch mehr Kontrolle über die Form des serialisierten XML wünschen, als das, was durch anwenden der XML-Serialisierungsattribute geboten wird. Mit den zwei Methoden der Schnittstelle, ReadXml und WriteXml, können Sie den serialisierten XML-Datenstrom vollständig steuern. Sie können auch das XML-Schema steuern, das für den Typ generiert wird, indem Sie die XmlSchemaProviderAttribute anwenden.

Unterstützung der Laufzeit-Serialisierung

Laufzeitliche Serialisierung ist eine Technologie, die von .NET Remoting verwendet wird. Wenn Sie denken, dass Ihre Typen mit .NET Remoting transportiert werden, müssen Sie sicherstellen, dass sie die Runtime-Serialisierung unterstützen.

Die grundlegende Unterstützung für Laufzeitserialisierung kann durch die Anwendung von SerializableAttribute bereitgestellt werden, und komplexere Szenarien umfassen die Implementierung eines einfachen Musters zur Laufzeitserialisierung (Indem ISerializable implementiert und der Serialisierungskonstruktor bereitgestellt wird).

✔️ ERWÄGEN Sie Unterstützung der Laufzeitserialisierung, wenn die Typen zusammen mit .NET-Remotezugriff verwendet werden sollen. Der System.AddIn-Namespace verwendet z. B. .NET-Remotezugriff, sodass alle zwischen System.AddIn-Add-Ins ausgetauschten Typen Laufzeitserialisierung unterstützen müssen.

✔️ ERWÄGEN SIE die Implementierung des serialisierbaren Laufzeitmusters, wenn Sie die vollständige Kontrolle über den Serialisierungsprozess wünschen. Wenn Sie beispielsweise Daten transformieren möchten, wenn sie serialisiert oder deserialisiert werden.

Das Muster ist sehr einfach. Sie müssen lediglich die ISerializable Schnittstelle implementieren und einen speziellen Konstruktor bereitstellen, der verwendet wird, wenn das Objekt deserialisiert wird.

✔️ DO machen Sie den Serialisierungskonstruktor geschützt und stellen Sie zwei Parameter bereit, die genau wie im Beispiel hier gezeigt getypt und benannt sind.

[Serializable]
public class Person : ISerializable
{
    protected Person(SerializationInfo info, StreamingContext context)
    {
        // ...
    }
}

✔️ IMPLEMENTIEREN Sie die ISerializable-Member explizit.

✔️ WENDEN Sie einen Linkaufruf auf die ISerializable.GetObjectData-Implementierung an. Dadurch wird sichergestellt, dass nur der voll vertrauenswürdige Kern und der Runtime Serializer Zugriff auf das Mitglied haben.

© Teile 2005, 2009 Microsoft Corporation. Alle Rechte vorbehalten.

Nachdruck mit freundlicher Genehmigung von Pearson Education, Inc., aus dem Buch Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries, 2nd Edition von Krzysztof Cwalina und Brad Abrams, veröffentlicht am 22. Oktober 2008 von Addison-Wesley Professional als Teil der Microsoft Windows Development Series.

Siehe auch