CodeGym /Kurse /C# SELF /Einführung in die Serialisierung

Einführung in die Serialisierung

C# SELF
Level 43, Lektion 0
Verfügbar

1. Einführung

Stell dir vor, dein Objekt im Programm ist so ein komplizierter, schöner LEGO-Bausatz. Er besteht aus vielen Teilen, jedes an seinem Platz, und zusammen ergibt das ein Ganzes. Solange der Bausatz auf deinem Tisch steht (im Speicher des Computers), ist alles gut. Aber was, wenn du ihn zu einem Freund bringen musst (über das Netzwerk schicken) oder einfach in eine Kiste packen willst, bis du ihn wieder brauchst (auf die Festplatte speichern)? Du kannst ihn ja nicht einfach so in eine flache Schachtel legen! Er würde auseinanderfallen!

Genau dafür — das sorgfältige Zerlegen des Objekts in Teile, um es sicher zu speichern oder zu übermitteln — gibt es Serialisierung. Das ist der Prozess, dein Objekt aus seinem "lebendigen" Zustand im Speicher in eine Bytefolge (oder eine textuelle Darstellung) zu verwandeln, die du in eine Datei schreiben, über das Netzwerk senden oder in die Zwischenablage legen kannst. Im Grunde ist das so, als würdest du deinen LEGO-Bausatz vorsichtig auseinandernehmen, alle Teile in Tütchen packen, beschriften und in eine Schachtel für den Transport oder die Aufbewahrung legen.

flowchart LR
    ObjectInMemory(Objekt im Speicher)
    Serialize[SERIALISIERUNG]
    BytesOrText[Bytes / Textdatei / JSON / XML]
    Deserialize[DESERIALISIERUNG]
    ObjectAgain(Objekt wieder im Speicher)

    ObjectInMemory -->|serialize| Serialize
    Serialize --> BytesOrText
    BytesOrText -->|deserialize| Deserialize
    Deserialize --> ObjectAgain

Und natürlich, wenn wir etwas verpackt haben, müssen wir es auch wieder auspacken können! Der umgekehrte Prozess heißt Deserialisierung. Das ist, wenn du die Schachtel mit den Tütchen LEGO-Teilen nimmst, sie auskippst und dann den Anweisungen folgst (oder dich erinnerst, wie es zusammengebaut war), um das Objekt im Speicher genau in dem Zustand wiederherzustellen, in dem es vor dem Verpacken war. So läuft das — Magie!

Der Begriff "Serialisierung" bedeutet wörtlich "sequenzielle Darstellung". Wir nehmen eine komplexe, möglicherweise im Speicher verstreute Struktur (ein Objekt kann auf andere Objekte, Collections usw. verweisen und so einen ganzen "Objektgraphen" bilden) und verwandeln sie in eine lineare, sequentielle Form, die sich leicht schreiben oder übertragen lässt.

2. Warum reicht einfach File.WriteAllText nicht?

Gute Frage! Wenn alle Daten einfache Strings oder Zahlen wären, kämen wir ohne Serialisierung aus. Aber in der echten Welt arbeiten unsere Anwendungen mit komplexen Modellen: Kunden, Bestellungen, Produkte, Studenten, Helden, Level. All das sind Objekte im Speicher. Und deshalb ist Serialisierung dein bester Freund:

Zustand der Anwendung speichern

Stell dir vor, du entwickelst einen Texteditor. Der Nutzer tippt Text, ändert Schriftarten, fügt Bilder ein. All diese Daten (Text, Einstellungen, Cursor-Position) sind im Wesentlichen Objekte in deinem Programm. Wenn der Nutzer auf "Speichern" klickt, willst du, dass beim nächsten Start alles genau so da ist, wie er es verlassen hat. Serialisierung erlaubt es, alle relevanten Objekte "einzufrieren" und auf die Festplatte zu schreiben, und sie beim Laden wieder "aufzutauen". Das ist wie "Spiel speichern" in Videospielen. Du willst ja nicht das ganze Level nochmal spielen müssen, wenn der Strom ausgeht, oder?

Daten zwischen Anwendungen austauschen

Dein C#-Programm kommuniziert vielleicht mit einem Webserver, der in Python geschrieben ist. Oder deine Mobile-App (z. B. auf Xamarin oder MAUI) spricht mit einem .NET-Server. Diese Programme haben keinen gemeinsamen Speicher. Um Daten auszutauschen, brauchen sie ein gemeinsames, verständliches Format. Serialisierung wandelt Objekte in dieses gemeinsame Format (zum Beispiel JSON oder XML) um, das über das Netzwerk gesendet werden kann. Am anderen Ende des Drahtes deserialisiert der Empfänger diese Daten zurück in seine eigenen Objekte, die für seine Programmiersprache verständlich sind. Ohne Serialisierung müsstest du jedes Datenstück manuell "auspacken" und wieder zusammensetzen. Das wäre langsam, mühsam und fehleranfällig!

Stell dir vor, du verschickst ein Paket ins Ausland. Du kannst deine Sachen nicht einfach so losschicken; du musst sie nach internationalen Standards verpacken (Serialisierung). Am Ziel kann der Empfänger das Paket öffnen und seine Sachen herausnehmen (Deserialisierung).

Konfiguration der Anwendung

Oft haben Anwendungen viele Einstellungen: Fenstergröße, Pfade zu Dateien, zuletzt geöffnete Dokumente, Farbschema. Jede Einstellung einzeln in einer Variable zu halten und dann manuell in eine Einstellungsdatei (z. B. .ini oder .txt) zu speichern ist unpraktisch. Viel einfacher ist es, eine Klasse EinstellungenDerAnwendung zu definieren, in der jede Einstellung eine Property ist, und diese Einstellungs-Instanz einfach zu serialisieren. Beim Start: deserialisieren. Schön und praktisch!

Caching von Daten

Manchmal dauert das Abrufen von Daten (z. B. aus einer Datenbank oder von einem entfernten Server) lange. Um nicht bei jeder Anfrage neu zu laden, kannst du die Daten einmal holen, serialisieren und im Cache speichern (auf der Festplatte oder in einem speziellen Speicher). Bei der nächsten Anfrage prüfst du zuerst den Cache und, falls die Daten vorhanden sind, deserialisierst du sie. Das beschleunigt die Anwendung erheblich und reduziert die Last auf externen Datenquellen.

3. Grundidee: den "Zustand" speichern

Das wichtigste Konzept in der Serialisierung ist das Sichern des Zustands. Ein Objekt ist im Grunde die Summe seiner Felder und der zu diesem Zeitpunkt vorhandenen Werte. Serialisierung "fotografiert" diesen Zustand. Wenn wir ein Objekt deserialisieren, erstellen wir nicht einfach ein neues leeres Objekt, sondern rekonstruieren es mit genau den Feldwerten, die es zum Zeitpunkt der Serialisierung hatte.

Das ist mehr als nur Datenkopieren. Es ist ein tiefes Kopieren der Struktur und Werte, inklusive Referenzen auf andere Objekte, sofern der Serializer damit umgehen kann. Manche Serializer speichern sogar Informationen über den Typ des Objekts, sodass man beim Deserialisieren die richtige Klasse wiederherstellen kann, selbst wenn der genaue Typ zur Deserialisierungszeit vorher nicht bekannt ist.

Klassisches Beispiel: Serialisierung von Haustieren

Wir führen unsere App "Encyclopedia der Haustiere" weiter. Angenommen, wir haben so eine Klasse:

public class Pet
{
    public string Name { get; set; }
    public string Type { get; set; } // Zum Beispiel: "Cat", "Dog"
    public int Age { get; set; }
}

Wir wollen:

  • Eine Collection solcher Objekte im Speicher füllen,
  • Sie in eine Datei speichern,
  • Und später wiederherstellen (z. B. nach einem Neustart der Anwendung).

Schematisch sieht das so aus:


Collection List<Pet>
    ↓ serialisierung
    Datei (JSON, XML, Bytes)
    ↓ deserialisierung
Collection List<Pet> (wieder im Speicher!)

4. Welche Serialisierungsformate gibt es

Wie in der Transportwelt, wo es verschiedene Containerarten gibt (Pappkartons, Holzkisten, Metallcontainer), so gibt es in der Programmierung verschiedene Serialisierungsformate. Jedes hat seine Eigenschaften, Vor- und Nachteile.

Wir gehen jetzt nicht zu tief ins Detail, merk dir aber ein paar Namen, damit du in den nächsten Lectures verstehst, worum es geht:

  • JSON (JavaScript Object Notation): Das wahrscheinlich populärste Format heute. Es ist textbasiert, relativ menschenlesbar und weit verbreitet im Datenaustausch im Web. Es sieht aus wie Schlüssel-Wert-Paare in geschweiften Klammern. Im Kern ist es normaler Text, aber so strukturiert, dass Programme ihn leicht parsen können.
  • XML (Extensible Markup Language): Älter, aber immer noch verbreitet. Ein textbasiertes Format, das auf Tags basiert wie HTML und eine strenge Struktur hat. Oft verwendet für Konfigurationsdateien und Datenaustausch in Unternehmenssystemen. Ebenfalls menschenlesbar, aber oft "wortreich".
  • Binäre Formate: Diese speichern Daten nicht als Text, sondern direkt als Bytes, so wie sie im Speicher liegen. Sie sind in der Regel kompakter und schneller beim Serialisieren/Deserialisieren, aber für Menschen unlesbar. Man nutzt sie, wo maximale Performance oder minimale Dateigröße wichtig sind, z. B. beim Speichern von Spieldaten oder beim Übertragen großer Datenmengen zwischen eigenen Systemkomponenten.

Die Wahl des Formats hängt von der Aufgabe ab: Muss ein Mensch die Daten leicht lesen können? Ist Geschwindigkeit und Dateigröße wichtig? Auf welche Plattformen werden die Daten übertragen? Für den Austausch zwischen verschiedenen Systemen sind JSON und XML oft bevorzugt wegen ihrer Universaltauglichkeit. Für das Speichern innerhalb derselben Anwendung können binäre Formate schneller und effizienter sein.

Wie du siehst, ist Serialisierung ein mächtiges Werkzeug, das vielen modernen Anwendungen zugrunde liegt. Sie erlaubt unseren Programmen, ihre Daten zwischen Starts zu "erinnern", miteinander zu kommunizieren und komplexe Informationen effizient zu verwalten. In den nächsten Lectures reden wir nicht mehr nur über "Magie", sondern lernen, wie man sie selbst anwendet, mit .NET-Bibliotheken! Mach dich bereit, es wird spannend!

2
Aufgabe
C# SELF, Level 43, Lektion 0
Gesperrt
Dateicodierung konvertieren
Dateicodierung konvertieren
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION