1. Einführung
Zur Erinnerung: Strings in C# sind unveränderlich (immutable). Das heißt, nachdem ein String erstellt wurde, kannst du ihn nicht mehr ändern: Alle Operationen, die scheinbar den String "verändern", erzeugen in Wirklichkeit einen neuen String im Speicher.
Zum Beispiel, wenn du schreibst:
string hello = "Privet";
hello += " mir!"; // Sieht so aus, als hätte sich hello geändert, aber tatsächlich wurde ein neues Objekt erstellt!
Die Variable hello zeigt jetzt auf ein neues Objekt, und das alte (wenn es nirgendwo mehr verwendet wird) wird irgendwann vom Garbage Collector gelöscht. Wenn du solche Aktionen in einer Schleife oft wiederholst, kann es zu einem "Stau" im RAM kommen und die Performance bricht plötzlich ein. Das merkst du besonders, wenn du Tausende oder Millionen von Strings zusammenfügst: Bei jedem Schritt wird ein neuer String erstellt, alle Zeichen werden kopiert, alte Objekte hängen rum bis zum Garbage Collector, und plötzlich wird dein Programm langsam.
Und hier kommt der Held dieser Vorlesung ins Spiel – StringBuilder.
using System.Text; // ← unbedingt!
StringBuilder sb = new StringBuilder("Privet");
sb.Append(" mir!"); // Jetzt wird der String schnell und effizient verändert
Kennenlernen von StringBuilder
StringBuilder ist eine Klasse aus dem Namespace System.Text. Ihre Aufgabe: große Strings effizient zusammenbauen und verändern, ohne ständig neue Objekte zu erzeugen.
Analogie:
Wenn ein String (string) wie ein Mosaikstein ist, den du nur komplett austauschen kannst, dann ist StringBuilder wie eine Magnettafel, auf die du beliebig viele Mosaikstücke "kleben" und wieder abnehmen kannst, ohne jedes Mal eine neue Tafel zu holen, wenn du etwas hinzufügen oder entfernen willst.
Wann solltest du StringBuilder verwenden?
- Wenn du einen String oft veränderst (vor allem in einer Schleife).
- Wenn du Text aus vielen kleinen Stücken zusammensetzt.
- Wenn dir Geschwindigkeit und Speicherverbrauch wichtig sind.
Wann solltest du ihn NICHT verwenden?
- Wenn du nur 1-2 einfache String-Operationen hast – ein normaler string ist dann einfacher und lesbarer.
- Wenn du wirklich (aus irgendeinem Grund) jeden einzelnen Zustand des Strings behalten willst.
2. Erstellen und grundlegende Operationen mit StringBuilder
Namespace einbinden
Der Start ist easy: Vergiss nicht, den Namespace einzubinden.
using System.Text;// ← unbedingt!
Verschiedene Wege, einen neuen String zu erstellen
StringBuilder sb1 = new StringBuilder(); // Leer
StringBuilder sb2 = new StringBuilder("Start"); // Mit Anfangstext
StringBuilder sb3 = new StringBuilder(100); // Mit Platz für 100 Zeichen
Wichtige Methoden
var sb = new StringBuilder("Anfang");
sb.Append(" + haben neuen Text hinzugefügt"); // Am Ende anhängen
sb.AppendLine(" (und das mit Zeilenumbruch)"); // Mit \n anhängen
sb.Insert(0, "Start: "); // An Position 0 einfügen
sb.Remove(0, 7); // 7 Zeichen ab Position 0 löschen
sb.Replace("Text", "STRING"); // Alle "Text" durch "STRING" ersetzen
string result = sb.ToString(); // Endgültigen String holen
3. Effizienz von StringBuilder
Beispiel: Performance-Vergleich
Angenommen, du sollst einen String aus 10 000 Zahlen hintereinander bauen (vielleicht musst du alle Matrikelnummern deiner Kommilitonen ausgeben):
Naiver Ansatz (string)
string text = "";
for (int i = 0; i < 10000; i++)
{
text += i + " "; // Bei jedem Schritt wird ein neuer String erstellt!
}
Console.WriteLine(text.Substring(0, 100) + "..."); // Für kürzere Ausgabe
Optimaler Ansatz (StringBuilder)
var sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
sb.Append(i).Append(' '); // Geht auch in einer Kette!
}
Console.WriteLine(sb.ToString().Substring(0, 100) + "...");
Was ist der Unterschied?
Die erste Variante ist deutlich langsamer und kann viel mehr Speicher fressen. Die zweite ist schnell und sparsam beim RAM.
4. Die beliebtesten Methoden von StringBuilder
Append – hängt einen String oder anderen Typ (wird automatisch zu String konvertiert) an:
sb.Append("Text");
sb.Append(123); // 123 wird zu "123"
sb.Append('!'); // Zeichen
AppendLine – hängt einen String + Zeilenumbruch an:
sb.AppendLine("Zeile"); // Fügt "Zeile\n" an
Insert – fügt einen String an einer bestimmten Position ein:
sb.Insert(0, "Hello, "); // Am Anfang einfügen
Remove – löscht mehrere Zeichen:
sb.Remove(3, 4); // Löscht 4 Zeichen ab Position 3
Replace – ersetzt alle Vorkommen eines Substrings oder Zeichens:
sb.Replace("alt", "neu");
sb.Replace('a', 'A');
ToString – gibt den fertigen String zurück.
String kürzen
Im Gegensatz zu string kannst du bei einem StringBuilder-Objekt die Länge direkt setzen. Der String wird dann auf diese Länge gekürzt.
sb.Length = 10; // Alles nach dem 10. Zeichen verschwindet!
5. Besonderheiten und typische Fehler
Warum ToString() wichtig ist
Solange du mit StringBuilder arbeitest, hast du kein String, sondern ein spezielles Objekt "in der Hand". Viele Methoden (z.B. Console.WriteLine) akzeptieren das problemlos, weil es sich automatisch in einen String verwandeln kann, aber manchmal gibt's eine Überraschung – zum Beispiel, wenn du versehentlich mit einem normalen String vergleichst oder sowas machst wie:
if (sb == "Privet") { ... } // Ups! Das klappt nicht, selbst wenn sb "Privet" enthält
Das Ergebnis ist false: Es werden nicht Strings, sondern Objekte verschiedener Typen verglichen.
Richtig wäre:
if (sb.ToString() == "Privet") { ... }
Mutierbarkeit
Im Gegensatz zu string ist StringBuilder veränderbar (mutable)! Ein Objekt kann seinen Inhalt beliebig oft ändern, was den Geschwindigkeitsvorteil bringt.
Vergiss nicht das ToString() am Ende, sonst bekommst du keinen String, sondern einen mysteriösen Text wie System.Text.StringBuilder.
Puffergröße und deren Anpassung
Intern speichert StringBuilder ein Zeichen-Array. Wenn du schon vorher weißt, dass du einen richtig langen String "basteln" willst, kannst du dem Konstruktor die erwartete Länge mitgeben – das macht die Arbeit ein bisschen schneller.
var bigBuilder = new StringBuilder(50000); // Wir erwarten 50 Tausend Zeichen
Aber falls du dich verschätzt hast – kein Stress! StringBuilder vergrößert den Puffer bei Bedarf selbst, das dauert dann nur ein bisschen länger.
Speicherüberlauf?
Theoretisch, wenn du es komplett übertreibst und Milliarden von Zeichen anhängst, kannst du bei OutOfMemoryException landen, aber für normale Aufgaben passiert das praktisch nie.
GO TO FULL VERSION