Was ist [serialisierbar] und wann sollte ich es verwenden?

Antworten:

369

Was ist es?

Wenn Sie ein Objekt in einer .NET Framework-Anwendung erstellen, müssen Sie nicht darüber nachdenken, wie die Daten im Speicher gespeichert werden. Weil das .Net Framework das für Sie erledigt. Wenn Sie jedoch den Inhalt eines Objekts in einer Datei speichern, ein Objekt an einen anderen Prozess senden oder über das Netzwerk übertragen möchten, müssen Sie überlegen, wie das Objekt dargestellt wird, da Sie in ein anderes Format konvertieren müssen . Diese Konvertierung wird als SERIALISIERUNG bezeichnet.

Verwendung für die Serialisierung

Durch die Serialisierung kann der Entwickler den Status eines Objekts speichern und bei Bedarf neu erstellen, um Objekte zu speichern und Daten auszutauschen. Durch die Serialisierung kann ein Entwickler Aktionen ausführen, z. B. das Senden des Objekts an eine Remoteanwendung mithilfe eines Webdienstes, das Übergeben eines Objekts von einer Domäne an eine andere, das Übergeben eines Objekts durch eine Firewall als XML-Zeichenfolge oder das Aufrechterhalten der Sicherheit oder benutzerspezifisch Informationen über Anwendungen hinweg.

Auf SerializableAttributeeinen Typ anwenden , um anzugeben, dass Instanzen dieses Typs serialisiert werden können. Wenden Sie das SerializableAttributeEven an, wenn die Klasse auch die ISerializableSchnittstelle implementiert , um den Serialisierungsprozess zu steuern.

Alle öffentlichen und privaten Felder in einem Typ, die mit gekennzeichnet SerializableAttributesind, werden standardmäßig serialisiert, es sei denn, der Typ implementiert die ISerializableSchnittstelle, um den Serialisierungsprozess zu überschreiben. Der Standard-Serialisierungsprozess schließt Felder aus, die mit gekennzeichnet sind NonSerializedAttribute. Wenn ein Feld eines serialisierbaren Typs einen Zeiger, ein Handle oder eine andere Datenstruktur enthält, die für eine bestimmte Umgebung spezifisch ist und in einer anderen Umgebung nicht sinnvoll wiederhergestellt werden kann, möchten Sie möglicherweise NonSerializedAttributeauf dieses Feld anwenden .

Weitere Informationen finden Sie unter MSDN .

Bearbeiten 1

Jeder Grund, etwas nicht als serialisierbar zu markieren

Beim Übertragen oder Speichern von Daten müssen Sie nur die erforderlichen Daten senden oder speichern. So treten weniger Übertragungsverzögerungen und Speicherprobleme auf. So können Sie beim Serialisieren unnötige Datenblöcke deaktivieren.

CharithJ
quelle
1
@dwbartz Ihre Frage wird hier beantwortet Link
jayasurya_j
2
Schöne Erklärung, wäre schön, dies dem Attribut in MSDN hinzuzufügen =)
Martea
@ jayasurya_j Schade, dass die akzeptierte Antwort nicht viel über die privaten Teile
Alexander
1
Gute Erklärung
Zakir HC
42

Einige praktische Anwendungen für das [Serializable]Attribut:

  • Speichern des Objektstatus mithilfe der binären Serialisierung; Sie können ganz einfach ganze Objektinstanzen in Ihrer Anwendung in einer Datei oder einem Netzwerk-Stream speichern und dann durch Deserialisieren neu erstellen. Überprüfen Sie die BinaryFormatterKlasse in System.Runtime.Serialization.Formatters.Binary
  • Das Schreiben von Klassen, deren Objektinstanzen mit Clipboard.SetData()- nicht serialisierbaren Klassen in der Zwischenablage gespeichert werden können, kann nicht in die Zwischenablage gestellt werden.
  • Schreiben von Klassen, die mit .NET Remoting kompatibel sind; Im Allgemeinen muss jede Klasseninstanz, die Sie zwischen Anwendungsdomänen übergeben (mit Ausnahme derjenigen, die sich von erstrecken MarshalByRefObject), serialisierbar sein.

Dies sind die häufigsten Anwendungsfälle, auf die ich gestoßen bin.

Bradley Smith
quelle
41

Da es sich bei der ursprünglichen Frage um das SerializableAttribute handelte, sollte beachtet werden, dass dieses Attribut nur bei Verwendung von BinaryFormatter oder SoapFormatter gilt.

Es ist etwas verwirrend, es sei denn, Sie achten wirklich auf die Details, wann Sie es verwenden und was sein eigentlicher Zweck ist.

Es hat NICHTS mit XML- oder JSON-Serialisierung zu tun.

Mit dem SerializableAttribute werden die ISerializable-Schnittstelle und die SerializationInfo-Klasse verwendet. Diese werden auch nur mit dem BinaryFormatter oder SoapFormatter verwendet.

Wenn Sie nicht beabsichtigen, Ihre Klasse mit Binary oder Soap zu serialisieren, markieren Sie Ihre Klasse nicht als [serialisierbar]. XML- und JSON-Serialisierer sind sich ihrer Existenz nicht einmal bewusst.

BLaminack
quelle
16
"Es hat NICHTS mit XML- oder JSON-Serialisierung zu tun" - DANKE! Zum Schluss eine Erklärung, warum ich jede Klasse mit oder ohne dieses Attribut glücklich in XML serialisieren kann
userSteve
1
Hast du eine Quelle dafür?
Michiel van Oosterhout
"XML- und JSON-Serialisierer sind sich ihrer Existenz nicht einmal bewusst". Das weiß ich nicht. Als ich JSON eine Klasse über WCF formatierte, wurden die Eigenschaftsnamen mit einem vorangestellten Unterstrich versehen, wenn die Klasse war Serializableund ohne, wenn das Attribut entfernt wurde. So ist eine Störung möglich.
Jens
@Jens Wenn ich JSON.net richtig verstanden habe, ist es mir egal, aber asp.net ändert dieses Verhalten ein wenig. Ich glaube, Sie können dies mit den Attributen JsonObject / JsonProperty umgehen.
Basis
29

Bei der Serialisierung wird ein Objekt in einen Bytestrom konvertiert, um das Objekt zu speichern oder in den Speicher, eine Datenbank oder eine Datei zu übertragen.

Wie Serialisierung funktioniert

Diese Abbildung zeigt den gesamten Serialisierungsprozess.

Geben Sie hier die Bildbeschreibung ein

Das Objekt wird in einen Stream serialisiert, der nicht nur die Daten enthält, sondern auch Informationen über den Objekttyp, wie z. B. Version, Kultur und Assemblyname. Von diesem Stream kann es in einer Datenbank, einer Datei oder einem Speicher gespeichert werden.

Details in msdn.

Mahbubur Rahman
quelle
14

Serialisierung

Bei der Serialisierung wird ein Objekt oder eine Reihe von Objektgraphen in einen Stream konvertiert. Bei der binären Serialisierung handelt es sich um ein Byte-Array

Verwendung der Serialisierung

  1. Speichern Sie den Status eines Objekts in einer Datei, Datenbank usw. und verwenden Sie diese.
  2. So senden Sie ein Objekt von einem Prozess an einen anderen (App Domain) auf demselben Computer und senden es über Kabel an einen Prozess, der auf einem anderen Computer ausgeführt wird.
  3. So erstellen Sie einen Klon des ursprünglichen Objekts als Backup, während Sie am Hauptobjekt arbeiten.
  4. Eine Reihe von Objekten kann einfach in die Zwischenablage des Systems kopiert und dann in dieselbe oder eine andere Anwendung eingefügt werden

Im Folgenden finden Sie einige nützliche benutzerdefinierte Attribute, die während der Serialisierung eines Objekts verwendet werden

[Serializable] -> Wird verwendet, wenn wir das serialisierbare Objekt markieren. [NonSerialized] -> Wird verwendet, wenn das Feld eines Objekts nicht serialisiert werden soll. [OnSerializing] -> Wird verwendet, wenn beim Serialisieren eines Objekts eine Aktion ausgeführt werden soll. [OnSerialized] -> Wird verwendet, wenn nach dem Serialisieren eines Objekts in den Stream eine Aktion ausgeführt werden soll.

Unten sehen Sie ein Beispiel für die Serialisierung

[Serializable]
    internal class DemoForSerializable
    {
        internal string Fname = string.Empty;
        internal string Lname = string.Empty;

        internal Stream SerializeToMS(DemoForSerializable demo)
        {
            DemoForSerializable objSer = new DemoForSerializable();
            MemoryStream ms = new MemoryStream();
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(ms, objSer);
            return ms;
        }

        [OnSerializing]
        private void OnSerializing(StreamingContext context) {
            Fname = "sheo";
            Lname = "Dayal";
        }
        [OnSerialized]
        private void OnSerialized(StreamingContext context)
        {
       // Do some work after serialized object
        }

    }

Hier ist der aufrufende Code

class Program
    {
        string fname = string.Empty;
        string Lname = string.Empty; 

       static void Main(string[] args)
        {
            DemoForSerializable demo = new DemoForSerializable();

            Stream ms = demo.SerializeToMS(demo);
            ms.Position = 0;

            DemoForSerializable demo1 = new BinaryFormatter().Deserialize(ms) as DemoForSerializable;

            Console.WriteLine(demo1.Fname);
            Console.WriteLine(demo1.Lname);
            Console.ReadLine();
        }

    }
Sheo Dayal Singh
quelle