Menu

C# String: Length, Vergleich, Escape-Zeichen, Verbatim- und mehrzeilige Strings

Wie Strings in C# funktionieren: Unveränderlichkeit, Length und Indizierung, Vergleich mit ==, Equals und string.Compare, Escape-Zeichen, Verbatim-Strings mit @ und mehrzeiliger Text, Raw-String-Literale, Prüfung auf null und leer sowie Schleifen über Zeichen.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Ein string ist in C# eine Folge von UTF-16-Zeichen (char-Werten). Er ist ein Referenztyp, verhält sich aber in den entscheidenden Punkten wie ein Wert: Er ist unveränderlich, und == vergleicht den Text statt der Objektidentität. string ist das C#-Schlüsselwort für den .NET-Typ System.String; beide sind austauschbar.

Ausgabe:

Porto
5
0
*****
hi
Porto has 5 letters

Strings sind unveränderlich

Keine Methode ändert einen String an Ort und Stelle. ToUpper, Replace, Trim und jede andere Methode geben einen neuen String zurück und lassen das Original unangetastet. Den Rückgabewert zu vergessen ist ein sehr häufiger String-Bug:

Ausgabe:

[  maya  ]
[MAYA]
tea
tea and cake

Durch die Unveränderlichkeit lassen sich Strings sicher zwischen Threads teilen und als Dictionary-Schlüssel verwenden. Der Preis: Wer einen String in einer Schleife Stück für Stück aufbaut, erzeugt bei jedem Schritt einen neuen String; dafür nimmst du StringBuilder.

Length und Indizierung

Length ist eine Property (ohne Klammern). Der Indexer s[i] gibt den char an Position i zurück, gezählt ab 0, und ist schreibgeschützt:

Ausgabe:

7
A
1
IndexOutOfRangeException
XB-2931

Ab C# 8 geht auch ein Index vom Ende aus: code[^1] ist das letzte Zeichen, dasselbe wie code[code.Length - 1]. Um mehrere Zeichen auf einmal zu nehmen, siehe Substring.

Length zählt UTF-16-Codeeinheiten, nicht das, was ein Leser als Zeichen wahrnimmt. Die meisten Buchstaben der meisten Sprachen sind eine Einheit, aber Emojis und einige seltene Schriften brauchen zwei (ein Surrogatpaar), daher ist "👍".Length gleich 2.

Strings vergleichen

== und != vergleichen die Zeichen und beachten Groß- und Kleinschreibung. Für alles andere übergibst du einen StringComparison-Wert, der festlegt, wie verglichen wird:

Ausgabe:

False
False
True
True
apple first
True
False
False
True

Welcher Vergleich wann passt:

  • Ordinal vergleicht die numerischen Zeichencodes. Das ist schnell, vorhersagbar und auf jedem Rechner gleich. Nimm es für Bezeichner, Dateinamen, Schlüssel, Protokollwerte und alles, was keinem Menschen angezeigt wird.
  • OrdinalIgnoreCase ist dasselbe, ohne Beachtung der Schreibweise. Die richtige Wahl für Prüfungen ohne Groß- und Kleinschreibung, etwa bei Dateiendungen oder HTTP-Headern.
  • CurrentCulture (und CurrentCultureIgnoreCase) folgt den Regeln der Sprache des Benutzers und sortiert Wörter also so, wie es ein Wörterbuch in dieser Sprache tun würde. Nimm es zum Sortieren von Listen, die Benutzern angezeigt werden.
  • InvariantCulture verwendet kulturabhängige Regeln, die nicht von den Spracheinstellungen des Benutzers abhängen. Es hängt trotzdem von der Globalisierungsbibliothek ab: Modernes .NET nutzt ICU, .NET Framework nutzt Windows NLS, und beide können manche Strings unterschiedlich ordnen.

string.Compare(a, b) und a.CompareTo(b) ohne StringComparison verwenden die aktuelle Kultur, wodurch ihre Ergebnisse von Rechner zu Rechner variieren. Vermeide Vergleiche wie a.ToLower() == b.ToLower(): Sie erzeugen zwei neue Strings und liefern in manchen Kulturen falsche Ergebnisse (das türkische i mit und ohne Punkt ist der klassische Fall).

a.Equals(b) wirft eine NullReferenceException, wenn a null ist, während a == b und das statische string.Equals(a, b) sicher mit null umgehen.

Escape-Zeichen

In einem normalen String-Literal leitet ein Backslash eine Escape-Sequenz ein:

EscapeBedeutung
\nNeue Zeile (Zeilenvorschub)
\rWagenrücklauf
\tTabulator
\\Backslash
\"Doppeltes Anführungszeichen
\'Einfaches Anführungszeichen (nur in einem char-Literal nötig)
\0Nullzeichen
\uXXXXUTF-16-Zeichen per 4-stelligem Hex-Code, z. B. \u00e9
\U0001F44DZeichen per 8-stelligem Hex-Code; über U+FFFF wird es zu zwei char-Werten
\xH bis \xHHHHZeichen per 1 bis 4 Hex-Ziffern (vermeiden: die Länge ist mehrdeutig)
\a, \b, \f, \vSignalton, Rückschritt, Seitenvorschub, vertikaler Tabulator
\eEscape-Zeichen, U+001B (C# 13)

Ausgabe:

Name:	Ana
City:	Porto
She said "hi"
C:\temp\report.txt
cafe = cafe
' is a quote char

Eine unbekannte Sequenz wie "\d" ist ein Kompilierfehler (CS1009, unrecognized escape sequence). Genau das passiert, wenn ein Windows-Pfad oder ein regulärer Ausdruck als normaler String geschrieben wird.

Verbatim-Strings und mehrzeilige Strings

Ein vorangestelltes @ macht ein Literal zum Verbatim-String: Backslashes sind wörtliche Zeichen, und der String darf sich über mehrere Zeilen erstrecken. Die einzige verbleibende Escape-Sequenz ist "", die ein doppeltes Anführungszeichen erzeugt.

Ausgabe:

C:\Users\ana\Documents\notes.txt
\d{3}-\d{4}
He said "ready" and left.
Rua das Flores 12
4050-262 Porto
Portugal
first line
second line

Ein mehrzeiliger Verbatim-String enthält alles zwischen den Anführungszeichen, auch die Einrückung der Folgezeilen. Deshalb werden sie meist wie oben bündig am linken Rand geschrieben. Die enthaltenen Zeilenumbrüche sind die aus der Quelldatei, eine mit Windows-Zeilenenden gespeicherte Datei erzeugt also \r\n.

C# 11 hat Raw-String-Literale eingeführt, die beide Probleme lösen. Sie beginnen und enden mit drei oder mehr doppelten Anführungszeichen, brauchen überhaupt kein Escaping und entfernen die Einrückung, um die die schließenden Anführungszeichen eingerückt sind:

// C# 11 and later
string json = """
    {
      "name": "Ana",
      "path": "C:\temp"
    }
    """;
// The 4 spaces before the closing """ are removed from every line.

Enthält der Inhalt selbst """, beginne und ende stattdessen mit vier Anführungszeichen. Raw-Literale lassen sich auch mit Interpolation kombinieren ($"""..."""); siehe String-Interpolation.

Null, leer und Leerraum

Eine String-Variable kann null sein (gar kein String), leer ("", Länge 0) oder nur Leerraum enthalten. Zwei statische Hilfsmethoden prüfen diese Fälle ohne Risiko einer NullReferenceException:

Ausgabe:

null    empty: True   blank: True
""      empty: True   blank: True
"   "   empty: False  blank: True
"Ana"   empty: False  blank: False
True

Zur Validierung von Benutzereingaben ist string.IsNullOrWhiteSpace fast immer die richtige Wahl. string.Empty und "" sind derselbe Wert; was du schreibst, ist Stilfrage.

Schleifen über Zeichen

Ein String ist aufzählbar, also besucht foreach jeden char. Der Typ char hat statische Methoden, um Zeichen zu klassifizieren:

Ausgabe:

letters=6 digits=4 upper=1 symbols=1
!6202tesnuS

Strings verbinden

+ verkettet und funktioniert mit jedem Typ auf der anderen Seite (es ruft ToString() auf). Um viele Werte zu kombinieren, nimm lieber Interpolation oder string.Join:

Ausgabe:

Ana Silva, 31
Ana Silva, 31
AnaSilva
tea | coffee | juice
Total: 23
Total: 5

Die letzten beiden Zeilen zeigen eine Falle bei der Rangfolge: + wird von links nach rechts ausgewertet, sobald die linke Seite also ein String ist, ist jedes folgende + eine Verkettung. Setze Arithmetik innerhalb einer Verkettung in Klammern.

Häufig gestellte Fragen

Wie bekomme ich die Länge eines Strings in C#?

Mit der Property Length: "hello".Length ist 5. Sie ist eine Property, keine Methode, also ohne Klammern. Length zählt UTF-16-Codeeinheiten, daher zählt ein Emoji oder ein anderes Zeichen außerhalb der Basic Multilingual Plane als 2. Der Aufruf auf einem null-String wirft eine NullReferenceException.

Wie vergleiche ich Strings in C#?

a == b vergleicht den Text und beachtet Groß- und Kleinschreibung. Für Gleichheit ohne Beachtung der Schreibweise nimm string.Equals(a, b, StringComparison.OrdinalIgnoreCase). Zum Sortieren oder Ordnen von Strings nimm string.Compare(a, b, StringComparison.Ordinal) oder einen kulturabhängigen Vergleich, der eine negative Zahl, null oder eine positive Zahl zurückgibt.

Wie schreibe ich einen mehrzeiligen String in C#?

Stelle dem Literal ein @ voran, dann ist es ein Verbatim-String: Er kann sich über mehrere Zeilen erstrecken, Backslashes sind wörtlich, und ein doppeltes Anführungszeichen wird als "" geschrieben. Ab C# 11 erstrecken sich auch Raw-String-Literale, begrenzt durch """, über mehrere Zeilen, entfernen die gemeinsame Einrückung und brauchen überhaupt kein Escaping. Du kannst Zeilen auch mit \n oder Environment.NewLine verbinden.

Was ist ein Verbatim-String in C#?

Ein String-Literal mit vorangestelltem @, etwa @"C:\Users\ana". Escape-Sequenzen werden nicht verarbeitet, ein Backslash ist also einfach ein Backslash. Das macht ihn zur natürlichen Wahl für Windows-Pfade und reguläre Ausdrücke. Die einzige Escape-Sequenz darin ist "" für ein doppeltes Anführungszeichen.

Was ist der Unterschied zwischen string und String in C#?

Keiner. string ist das C#-Schlüsselwort als Alias für den .NET-Typ System.String, so wie int ein Alias für System.Int32 ist. Konvention ist, string für Deklarationen und string.IsNullOrEmpty(...) für statische Aufrufe zu verwenden, aber beide kompilieren zu genau demselben Code.

Welche Escape-Zeichen unterstützt C#?

\n Zeilenumbruch, \r Wagenrücklauf, \t Tabulator, \\ Backslash, \" doppeltes Anführungszeichen, \' einfaches Anführungszeichen, \0 Nullzeichen, \uXXXX ein UTF-16-Zeichen per Hex-Code, \U0001F600 ein Zeichen per 8-stelligem Code (es wird zu einem Surrogatpaar), \a Signalton, \b Rückschritt, \f Seitenvorschub, \v vertikaler Tabulator und \e (C# 13) Escape. Eine unbekannte Sequenz wie \d ist ein Kompilierfehler (CS1009). Deshalb werden reguläre Ausdrücke meist als Verbatim-Strings geschrieben.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S