Was ist der Unterschied zwischen der Verwendung des Serializable-Attributs und der Implementierung von ISerializable?

Antworten:

41

Wenn Sie das SerializableAttributeAttribut verwenden, fügen Sie ein Attribut zur Kompilierungszeit so in ein Feld ein, dass die Serialisierungsfunktionen zur Laufzeit anhand der Attribute wissen, was zu serialisieren ist, indem sie die Klasse / das Modul / die Assembly reflektieren Art.

[Serializable]
public class MyFoo { … }

Das Obige gibt an, dass die Serialisierungsfunktion die gesamte Klasse serialisieren sollte MyFoo, während:

public class MyFoo
{
    private int bar;

    [Serializable]
    public int WhatBar
    {
       get { return this.bar; }
    }
}

Mit dem Attribut können Sie selektiv auswählen, welche Felder serialisiert werden sollen.

Wenn Sie die ISerializableSchnittstelle implementieren , wird die Serialisierung effektiv mit einer benutzerdefinierten Version überschrieben, indem Sie überschreiben und (und einen Konstruktor des Formulars bereitstellenGetObjectData SetObjectDataMyFoo(SerializationInfo info, StreamingContext context) ) wird die Serialisierung der Daten genauer gesteuert.

Siehe auch dieses Beispiel einer benutzerdefinierten Serialisierung hier auf StackOverflow . Es wird gezeigt, wie die Serialisierung mit verschiedenen Versionen der serialisierten Daten abwärtskompatibel bleibt.

Hoffe das hilft.

t0mm13b
quelle
11
In welcher Version von .NET ist es in Ordnung, das SerializableAttribut einer Eigenschaft hinzuzufügen ? Laut MSDN kann es nur auf Klassen, Strukturen, Aufzählungen und Delegaten angewendet werden.
Hangy
5
Keiner. Das serialisierbare Attribut kann nicht auf Eigenschaften angewendet werden, sondern nur auf Klassen-, Struktur- und Aufzählungs- und Delegatdeklarationen.
Daniel Leiszen
3
Das Gegenteil SerializableAttributeist der Fall : Wenn die Klasse mit dekoriert ist , kann ein Mitglied NonSerializedAttributeals übersprungen markiert werden, wie mehrere Personen (und MSDN) sagten. Wenn die Rekonstruktion eines bestimmten Objekts in einer anderen Umgebung bedeutungslos ist, ist es ratsam, es nicht zu serialisieren. ..
Nurchi
20

Das SerializableAttribute weist das Framework an, den Standard-Serialisierungsprozess durchzuführen. Wenn Sie mehr Kontrolle benötigen, können Sie die ISerializable-Schnittstelle implementieren . Dann würden Sie Ihren eigenen Code einfügen, um das Objekt in der GetObjectDataMethode zu serialisieren und das an sie übergebene Objekt zu aktualisieren SerializationInfo.

Segfault
quelle
4
Wenn Sie ISerializable implementieren, ist es auch üblich (oder möglicherweise sogar erforderlich), den Deserialisierungskonstruktor zu implementieren: protected SomeClass (SerializationInfo-Info, StreamingContext-Kontext)
jrista
18
Beachten Sie, dass Sie die Klasse [Serializable] auch dann markieren müssen, wenn Sie die ISerializable-Schnittstelle implementieren.
Adam Lear
3

Über die ISerializableSchnittstelle können Sie eine andere als die Standard- Serialisierung implementieren . Wenn Sie die ISerializableSchnittstelle implementieren , müssen Sie die GetObjectDataMethode wie folgt überschreiben

public void GetObjectData (SerializationInfo serInfo, 
                                    StreamingContext streamContext)
{
   // Implement custom Serialization
}
Asad
quelle
1

ISerialize zwingt Sie, die Serialisierungslogik manuell zu implementieren, während das Markieren mit dem Attribut Serializable (meinten Sie das?) Dem Binary Serializer mitteilt, dass diese Klasse serialisiert werden kann. Es wird es automatisch tun.

Andrey
quelle
0

Durch das Erben von ISerializable können Sie die (De-) Serialisierung benutzerdefiniert implementieren. Wenn nur das Attribut Serializable verwendet wird, kann die (De-) Serialisierung nur durch Attribute gesteuert werden und ist weniger flexibel.

Logiknp
quelle
Die Deserialisierung erfolgt über den Deserialisierungskonstruktor. Siehe meinen Kommentar zur Segfaults-Antwort.
Jrista