## 14.2 Die Klasse »String« String-Variablen repräsentieren Zeichenfolgen mit einem ganz wesentlichen Charakteristikum: Sie sind unveränderlich. Ändern Sie den Inhalt einer Zeichenfolgevariablen durch eine neue Zuweisung, wird ein neues String-Objekt erzeugt und das alte verworfen. Dieses Phänomen können Sie sehr einfach verstehen, wenn Sie das folgende Codefragment schreiben:
    string text = "Hallo";
    Console.WriteLine(text.GetHashCode());
    text = "Berlin";
    Console.WriteLine(text.GetHashCode());
Das Ergebnis wird sein, dass unterschiedliche Hashcodes in der Konsole angezeigt werden. Diesem anscheinenden Nachteil steht aber auch ein Vorteil gegenüber, denn intern verwaltet die Laufzeitumgebung CLR eine Tabelle, die jeden String einer Anwendung enthält. Wenn Sie zur Laufzeit ein neues String-Objekt erzeugen, wird zuerst die Tabelle nach einem identischen String durchsucht. Ist ein solcher vorhanden, wird der neuen String-Variablen eine Referenz auf die bereits existierende Instanz zurückgeliefert, andernfalls wird der Pool vergrößert. Auch das können Sie sehr einfach prüfen, wenn Sie das Codefragment ein klein wenig ändern:
    string text = "Hallo";
    Console.WriteLine(text.GetHashCode());
    string text1 = "Hallo";
    Console.WriteLine(text1.GetHashCode());
Nun werden an der Konsole identische Hashcodes angezeigt. Wird eine Zeichenfolge häufig verändert, hat das eine Verschlechterung der Performance zur Folge. Sie sollten in solchen Fällen sollten Sie daher besser auf die Klasse StringBuilder zurückgreifen, die diesen Nachteil nicht hat. Verschwiegen werden darf dabei jedoch nicht, dass die Fähigkeiten einer StringBuilder-Zeichenfolge deutlich spärlicher sind als die einer string-Zeichenfolge. ### 14.2.1 Erzeugen eines Strings Im einfachsten Fall wird ein Objekt vom Typ String durch eine einfache Deklaration erzeugt:
    string str = "C# ist spitze!";
Das ist der Weg, den wir bisher meistens beschritten haben und der wohl auch die Regel darstellt. Es gibt aber noch weitere Möglichkeiten. Dazu sind in der Klasse String mehrere Konstruktoren definiert. Beispielsweise können Sie einem Konstruktor ein char-Array übergeben, aus dem ein String-Objekt erstellt wird:
    char[] charArr  = {'C','#',' ','4','.','0'};
    string strText = new String(charArr);
    Console.WriteLine(strText);
Dieses Codefragment bildet aus dem char-Array die Zeichenfolge »C# 4.0«. Mit einem weiteren Konstruktor können Sie eine Zeichenfolge zu erzeugen, die sich aus einer bestimmten Anzahl gleicher Zeichen zusammensetzt. Benötigen Sie beispielsweise eine Zeichenfolge aus zehn *, könnten Sie das mit
    string strtext = new String('*', 10);
erreichen. ### 14.2.2 Eigenschaften von »String« String weist nur zwei Eigenschaften auf: Length und Chars. Length liefert die Anzahl der Zeichen, und mit Chars können Sie auf ein einzelnes Zeichen aus der Zeichenfolge zugreifen. Die Definition von Chars, die in C# als Indexer implementiert ist, lautet wie folgt:
    public char this[int index] {get;}
Übergeben wird dem Indexer eine Zahl, die die Position eines Zeichens innerhalb der Zeichenfolge beschreibt, zum Beispiel:
    string text = "HALLO";
    char newChar = text[2];
Die char-Variable enthält damit das Zeichen »L«. ### 14.2.3 Methoden der Klasse »String« Sie werden sich oft mit der einfachen Existenz einer Zeichenfolge nicht zufrieden geben, da es sehr häufig vorkommt, dass Zeichenfolgen verglichen oder manipuliert werden müssen oder eine formatierte Ausgabe erwünscht ist. Die Klasse String bietet zu diesem Zweck eine Reihe von Methoden an, die wir uns nun ansehen wollen. #### Zeichenfolgen-Vergleiche Um zwei Zeichenfolgen zu vergleichen, haben Sie die Qual der Wahl, denn dazu stehen Ihnen mit Equals, Compare, CompareTo und CompareOrdinal gleich vier Methoden zur Verfügung. Alle sind sich ziemlich ähnlich und unterscheiden sich nur in kleinen Nuancen. Bekanntlich werden mit Equals standardmäßig zwei Referenzen miteinander verglichen. Da zwei String-Variablen, die denselben Inhalt haben, ein und dasselbe Objekt im Speicher referenzieren, können Sie diese Methode auch dazu benutzen, den Inhalt der Variablen miteinander zu vergleichen. Verweisen zwei Strings auf dieselbe Speicheradresse, muss deren Inhalt zwangsläufig identisch sein. Sehr ähnlich arbeitet auch Compare. Die Methode liefert jedoch keinen booleschen Wert, sondern einen Integer, der entweder < 0, 0 oder > 0 ist. Dazu ein Beispiel:
    string strText = "Hallo";
    string myString = "Hallo";
    if(String.Compare(strText, myString) == 0)
       Console.WriteLine("Die beiden Strings sind identisch");
Das Ergebnis an der Konsole bestätigt, dass beide Zeichenfolgen denselben Inhalt aufweisen. Ändern wir nun einen der beiden Strings von »Hallo« in »hallo«, und testen wir noch einmal. Diesmal erhalten wir keine Bestätigung, was uns zu folgender Aussage führt:
Hinweis
Standardmäßig wird bei String-Variablen zwischen Groß- und Kleinschreibung unterschieden.
Die Interpretation der Rückgabewerte von Compare, die ebenfalls für die Vergleichsmethode CompareTo gilt, können Sie Tabelle 14.2 entnehmen.

Tabelle 14.2 Die Rückgabewerte von String-Vergleichsoperationen

Rückgabewert | Beschreibung
< 0 | Der String des ersten Arguments ist kleiner als der des zweiten.
0 | Beide Strings sind gleich.
> 0 | Der String des ersten Arguments ist größer als der des zweiten.
Die spezifische Ländereinstellung entscheidet darüber, wann ein Zeichen als größer oder kleiner im Vergleich zu einem zweiten gilt. Im mitteleuropäischen Sprachraum ist festgelegt, dass den Großbuchstaben ein größerer Wert zugeordnet ist als ihrem kleingeschriebenen Pendant. Daher gilt:
    A > a
    B > b
Innerhalb von Groß- bzw. Kleinbuchstaben gilt die Reihenfolge, dass A < B < C bzw. a < b < c ist. Ganz allgemein kann man die Sortierregel dann wie folgt beschreiben:
    a < A < b < B < c < C ... < y < Y < z < Z
Compare durchläuft die beiden zu vergleichenden Zeichenfolgen Zeichen für Zeichen. Dabei wird zunächst die Wertigkeit eines Buchstabens im Alphabet festgestellt, und bei Gleichheit wird zwischen Groß- und Kleinschreibung unterschieden. CompareOrdinal vergleicht zwei Zeichenfolgen auf Basis der ANSI-Werte. Die Methode durchläuft dazu die beiden Zeichenfolgen Zeichen für Zeichen. Stimmt auch das letzte Zeichen in beiden Zeichenfolgen überein, ist der Rückgabewert 0. Stellt die Methode an einer Ordinalposition keine Übereinstimmung fest, bricht sie ab und liefert als Rückgabewert die Differenz der Zeichencodes. Tabelle 14.3 zeigt dies mit den Zeichenfolgen str1 und str2.

Tabelle 14.3 »CompareOrdinal«-Vergleichsergebnisse

str1 | str2 | Rückgabewert
H | A | 7
H | a | –25
H | P | –8
H | p | –40
H | H | 0
H | h | –32
h | H | 32
Fassen wir zum Abschluss noch einmal alle Vergleichsoperationen zur besseren Übersicht in einer Tabelle zusammen.

Tabelle 14.4 Die Vergleichsmethoden der »String«-Klasse

Vergleichsmethode | Beschreibung
Equals | Stellt fest, ob zwei Strings denselben Inhalt und folglich auch dieselbe Referenz haben.
Compare | Klassenmethode, die die lexikalische Reihenfolge der Zeichen in zwei Strings miteinander vergleicht
CompareOrdinal | Klassenmethode, die die lexikalische Reihenfolge der Zeichen in zwei Strings auf Basis der ANSI-Werte miteinander vergleicht
CompareTo | Instanzmethode, die die lexikalische Reihenfolge der Zeichen in zwei Strings miteinander vergleicht
#### Suchen in einer Zeichenkette Viele Aufgaben, die sich im Zusammenhang mit Zeichenfolgen stellen, beziehen sich auf die Suche nach einem bestimmten Zeichen oder nach einer Abfolge von Zeichen innerhalb einer Zeichenfolge. Das Ergebnis der Suche wird beispielsweise zur Konstruktion eines neuen Strings oder als Anweisung innerhalb einer anderen, äußeren Anweisung benötigt. Wir wollen uns im Folgenden diese Methoden und ihren Einsatz anschauen. Doch zunächst verschaffen wir uns einen ersten Überblick: StartsWith EndsWith IndexOf LastIndexOf Substring Fangen wir mit den beiden erstgenannten Methoden an, die in ihrer Funktionalität einander sehr ähnlich sind: Mit StartsWith und EndsWith wird der Anfang oder das Ende einer Zeichenfolge auf eine vorgegebene Zeichensequenz hin überprüft. Beide liefern als Ergebnis ihres Aufrufs einen booleschen Wert zurück. Die Anzahl der dem Parameter mitgeteilten Zeichen spielt keine Rolle, es kann sich um ein einzelnes Zeichen handeln oder um eine Zeichenfolge. Mit
    string str = "Eine Kröte überquert die Fahrbahn";
    if ( str.StartsWith("Ein") )...
werden Sie demnach das Ergebnis true erhalten. In gleicher Weise lässt sich die Methode EndsWith einsetzen:
    string str = "Eine Kröte überquert die Fahrbahn";
    if ( str.StartsWith("Bahn") )...
Beachten Sie, dass die Groß- und Kleinschreibung auch bei der Untersuchung einer Zeichenfolge berücksichtigt wird. Daher wird der Rückgabewert in diesem Fall false sein. Mit IndexOf bzw. LastIndexOf lässt sich das erste oder das letzte Auftreten eines Zeichens oder einer Zeichenkette ermitteln. Beide Methoden sind vielfach überladen und erlauben die Übergabe eines char ebenso wie die Übergabe einer Zeichenfolge, nach der gesucht werden soll. Der Rückgabewert ist die Position, an der das Zeichen zum ersten Mal auftritt (bzw. an der die Zeichen zum ersten Mal auftreten). Ist die Suche erfolglos, ist der Rückgabewert –1. Im einfachsten Fall ähnelt die Funktionalität der beiden Methoden der von StartsWith und EndsWith. Die Überladung ermöglicht es aber, die Suche ab einer bestimmten Position zu beginnen und – falls gewünscht – die Anzahl der Positionen anzugeben, an denen das Original mit dem Suchstring verglichen wird. Das folgende Codefragment demonstriert den Einsatz der IndexOf-Methode.
    string text;
    text = "Da wird der Hund in der Pfanne verrückt.";
    int position = -1;
    do {
      position++;
      pos = text.IndexOf("der", position);
      if(position == -1)
        Console.WriteLine("Ende des Strings erreicht.");
      else
        Console.WriteLine("Vorkommen an Position {0}", position);
    } while(!(position == -1));
Wir geben zwar nur eine statische Zeichenfolge vor, aber das sollte uns in dieser Demonstration genügen. Gesucht wird in dieser Zeichenfolge der Teilstring »der«. Wir deklarieren zunächst die Variable position, die in der folgenden do-Schleife als Positionszeiger dient und der das Ergebnis des Aufrufs IndexOf zugewiesen wird. Wird der gesuchte Teilstring gefunden, muss der Positionszeiger um eine Position verschoben werden, um nicht in einer Endlosschleife zu enden. Das hat aber zur Konsequenz, dass vor dem Eintritt in die Schleife position mit –1 vorinitialisiert werden muss, damit die Suche beim ersten Schleifendurchlauf auch mit 0 startet. Der Ausstieg aus der Schleife ist gewährleistet, wenn IndexOf das Ergebnis –1 liefert. Innerhalb des zu durchsuchenden Strings ist der Suchstring an den Positionen 8 und 20 enthalten. Beachten Sie, dass dem ersten Zeichen im zu durchsuchenden String der Index 0 zugeordnet ist. Etwas allgemeiner gehalten ist die sehr flexibel einsetzbare Methode Substring, die überladen ist und die aus einer gegebenen Zeichenfolge einen Teilstring zurückliefert. Substring wird in jedem Fall der Index der Startposition übergeben, ab der ein vorhandener String ausgewertet wird. Übergeben Sie einen zweiten Parameter, können Sie zudem die Anzahl der einzulesenden Zeichen ab der im ersten Parameter angegebenen Position festlegen. Wollen Sie beispielsweise die ersten sieben Zeichen einer Zeichenfolge einlesen, würde die Anweisung dazu wie folgt lauten:
    string text = "Projektmappen-Explorer";
    string teilString = text.Substring(0, 7);
Die Variable teilString wird den Inhalt »Projekt« haben. Benötigen Sie einen Teilabschnitt vom Ende eines Strings – nehmen wir an, die letzten acht Zeichen –, setzen Sie den Positionszeiger auf das erste einzulesende Zeichen, indem Sie von der Gesamtlänge des Strings die Anzahl der einzulesenden Zeichen subtrahieren:
    String text = "Projektmappen-Explorer";
    string teilString = teilString.Substring(teilString.Length - 8, 8);
Nun lautet der Inhalt von teilString »Explorer«. #### Die Methoden »Trim« und »Pad« Stellen Sie sich vor, Sie schreiben ein Programm, das auf eine Datenbank zugreift. In der Datenbank befindet sich eine Tabelle mit dem Kundenstamm eines Unternehmens. Aus dieser Tabelle soll ein ganz bestimmter Datensatz herausgegriffen werden, beispielsweise um die Kundendaten einzusehen oder zu ändern. Um nicht die gesamte Kundenliste der Reihe nach zu durchforsten (natürlich auch, um die Ressourcen zu schonen und um eine gute Performance der Anwendung zu gewährleisten), sollte der Anwender dazu aufgefordert werden, den Namen des Unternehmens anzugeben. Diese Eingabe wird nachfolgend dazu benutzt, in der Tabelle den passenden Datensatz zu suchen und ihn an den Anwender zurückzugeben. Nehmen wir an, der Anwender sucht nach dem Unternehmen Tollsoft GmbH und gibt dazu das folgende Suchkriterium ein, nach dem der Kundenstamm der Tabelle durchsucht wird:
     Tollsoft GmbH
Fällt Ihnen etwas auf? Wenn nicht, dann sei Ihnen gesagt, Sie machen denselben Fehler wie unser fiktiver Anwender – der Datensatz wird nämlich nicht gefunden. Der Grund ist ganz trivial: Vor dem Namen des Unternehmens steht – kaum bemerkbar – ein Leerzeichen. »Tollsoft GmbH« und »Tollsoft GmbH« sind aber unterschiedliche Firmennamen – zumindest aus Sicht des Programms. Fehler dieser Art schleichen sich sehr schnell ein und müssen daher schon bei der Programmentwicklung ausgeschlossen werden. Die Klasse String stellt Ihnen dazu die Methoden Trim, TrimStart und TrimEnd zur Verfügung. Trim entfernt bestimmte Zeichen sowohl am Anfang als auch am Ende einer Zeichenfolge, und TrimStart und TrimEnd entfernen bestimmte Zeichen am Anfang bzw. Ende einer Zeichenfolge. Sehen wir uns die Definition der Methode Trim an, die einfach überladen ist:
    public string Trim();
    public string Trim(params char[]);
Die erste Variante wird auf ein String-Objekt aufgerufen und entfernt automatisch die Leerzeichen, die sich am Anfang und am Ende der Zeichenfolge befinden. Die parameterlose Trim-Methode ist damit auf Leerzeichen spezialisiert und dürfte in den meisten Anwendungsfällen genügen – natürlich auch in dem, der anfangs beschrieben worden ist. Die parametrisierte Version ist deutlich leistungsfähiger. Ihr wird ein char-Array übergeben, das diejenigen Zeichen enthält, die weder am Anfang noch am Ende der Zeichenfolge erlaubt sind. Das folgende Codefragment zeigt die Wirkungsweise der Methode:
    string text = "Am Straßenrand sitzt eine Kröte.";
    char[] charArr = {' ','m','A','.'};
    text = text.Trim(charArr);
Wir definieren das Array so, dass weder das Leerzeichen noch ein Punkt oder die Buchstaben A und m zugelassen sind. Die aus dem Aufruf der Trim-Methode resultierende Zeichenfolge wird lauten:
    Straßenrand sitzt eine Kröte
Sehr ähnlich arbeiten auch die beiden Methoden TrimStart und TrimEnd, die nicht überladen sind und ein char-Array als Übergabeparameter erwarten. Die Methoden PadLeft und PadRight schneiden keine Zeichen an den String-Enden ab, sondern fügen bestimmte Zeichen entweder am Anfang oder am Ende der Zeichenfolge hinzu. Auch diese Methoden sind überladen. Wir wollen uns kurz beide Parameterlisten anschauen:
    public string PadLeft(int);
    public string PadLeft(int, char);
Dieselbe Überladungsliste weist auch die Methode PadRight auf. Die einfach parametrisierte Variante hängt Leerzeichen am Anfang (PadLeft) oder Ende (PadRight) der Zeichenfolge an. Der Integer gibt an, wie lang die am Ende resultierende Zeichenfolge insgesamt werden soll – also einschließlich der Anzahl der Zeichen des Strings selbst. Wenn Sie einen Wert übergeben, der gleich oder kleiner der Länge der Zeichenfolge ist, verpufft der Methodenaufruf wirkungslos. Daher ist es sinnvoll, die Länge der Zeichenfolge zu bestimmen und dazu die Anzahl der gewünschten Leerzeichen zu addieren.
    string text = "Kaffeepause";
    Console.WriteLine(text.PadLeft(text.Length + 3));
Wenn Sie ein anderes Zeichen am Anfang oder Ende des Strings wünschen, müssen Sie sich für die zweite Variante der Methode entscheiden. Dem zweiten Parameter übergeben Sie das gewünschte Zeichen als char:
    string text = "Kaffeepause";
    text = text.PadLeft(text.Length + 3, '*');
    text = text.PadRight(text.Length + 3, '*');
    // Das Ergebnis der Operationen lautet "***Kaffeepause***".
#### Zeichenfolgen ändern Bisher haben wir Strings verglichen, nach bestimmten Zeichensequenzen in einem String gesucht und am Anfang oder am Ende eines Strings Zeichen beliebiger Länge angehängt. Eine Reihe weiterer Methoden eröffnet uns die Möglichkeit, in der Zeichenfolge einzelne Zeichen zu manipulieren, indem wir sie durch andere ersetzen oder schlichtweg aus dem String löschen. Zu diesen Methoden gehören: Insert Remove Replace Split ToUpper ToLower ToUpper und ToLower sind sehr einfach einzusetzen. Sie wandeln alle Zeichen einer Zeichenfolge entweder in Großbuchstaben (ToUpper) oder in Kleinbuchstaben (ToLower) um. Aus
    string text = "Visual Studio .NET";
wird mit
    text = text.ToUpper();
der Inhalt zu:
    VISUAL STUDIO .NET
#### Einsetzen oder Ersetzen eines Teilstrings Manchmal ist es notwendig, eine Zeichenfolge ab einer bestimmten Position zu erweitern, ohne dabei aus dem Original Zeichen durch Überschreiben zu löschen. Hier spielt Insert seine Möglichkeiten aus:
    public string Insert(int, string);
Dem ersten Parameter übergeben Sie die Position, ab der die im zweiten Parameter genannte Zeichenkette eingefügt werden soll. Aus der Zeichenfolge
    string text = "C# ist spitze.";
wollen wir die noch näher an der Wahrheit liegende Zeichenfolge
    "C# ist absolute Spitze."
formulieren. Den String, den wir mittels Insert einfügen wollen, kennen wir. Was noch fehlt, ist die Position, ab der eingefügt werden soll. Dabei hilft IndexOf weiter:
    text = text.Insert(text.IndexOf("Spitze"), "absolute ");
Diese Methode liefert den Index des ersten Zeichens der übergebenen Zeichenfolge Spitze, der als Einfügemarke für das zusätzliche Wort von Insert benutzt wird. Mit Replace können Sie einen String – man sollte besser von einem Teilstring sprechen – durch einen anderen ersetzen. Replace ist aber nicht nur auf den Austausch einer bestimmten Zeichensequenz in einer Zeichenfolge beschränkt, es kann auch jedes Zeichen durch ein anderes ersetzt werden.
    public string Replace(char, char);
    public string Replace(string, string);
Der erste Parameter beschreibt das zu ersetzende Zeichen bzw. die zu ersetzende Zeichenfolge. Wodurch ersetzt werden soll, weiß der zweite Parameter zu berichten. Sollte Ihnen der Satz »Schule macht viel Spaß« nicht gefallen, können Sie ihn mit
    text = text.Replace("viel", "nie");
in eine möglicherweise ehrlichere Aussage überführen. #### Die »Split«-Methode Es können Situationen auftreten, in denen mehrere Zeichenketten vorliegen, die Sie für eine bestimmte Operation wie eine einzige Zeichenkette behandeln wollen. Stellen Sie sich dazu vor, Sie möchten Ihre Adresse über das Netzwerk einer anderen Person mitteilen. Dazu können Sie zuerst Ihren Vornamen bekannt geben, im Anschluss daran Ihren Zunamen, schließlich den Wohnort usw. Besser wäre es, die vollständige Information in einem String zu verschicken und sich mit dem Empfänger auf ein Format zu einigen, nach dem der übermittelte String wieder in seine ursprünglichen Einzelstrings zerlegt werden kann und die Substrings zu interpretieren sind. Schließlich müssen beide Parteien wissen, ob es sich bei »Otto« um den Vor- oder Zunamen handelt. Neben der Interpretationsreihenfolge müssen Sie ein als Separator dienendes Zeichen festlegen, das die Teilzeichenfolgen voneinander trennt. Haben sich Sender und Empfänger darüber geeinigt, lässt sich die beim Empfänger eingehende Zeichenfolge in die ursprünglichen Teilstrings zerlegen. Die String-Klasse unterstützt mit ihrer Methode Split das eben beschriebene Szenario des Zerlegens einer Zeichenfolge in Teilstrings. Schauen wir uns zunächst einmal die Definition der Split-Methode an:
    public string[] Split(params char[]);
Die Methode durchsucht den String, auf den Split aufgerufen wird, nach den spezifizierten Separatoren, die dem Parameter mitgeteilt werden. Da dieser Parameter als params definiert ist, können durchaus mehrere verschiedene Trennzeichen definiert werden. Das eröffnet Interpretationsmöglichkeiten hinsichtlich der Teilzeichenfolgen. So könnten Sie beispielsweise festlegen, dass als Separator zwischen dem Vor- und dem Zunamen ein Semikolon benutzt wird, zwischen dem Zunamen und dem Wohnort ein Ausrufezeichen usw. Die einzelnen Teilstrings werden in einem String-Array an den Aufrufer zurückgegeben. Wir wollen uns die Arbeitsweise dieser etwas komplexeren Methode an einem Beispiel verdeutlichen und legen dazu fest, das Semikolon als Separator zu benutzen. Eine Methode, die in der Lage ist, eine ihr übergebene Zeichenfolge wieder in die ursprünglichen Teilstrings zu zerlegen, könnte wie folgt aussehen:
    public static void GetSubstrings(string text) {
      string[] myStr = text.Split(';');
      for(int i = 0; i <= myStr.GetUpperBound(0); i++)
        Console.WriteLine(myStr[i]);
    }
Dem Aufruf der Methode GetSubstrings wird eine Zeichenfolge übergeben, deren Teilstrings durch ein Semikolon getrennt sind. In der Methode wird der String in seine Teilstrings zerlegt und dem Array myStr zugewiesen. Die Aufsplittung erfolgt mit der Split-Methode auf das Objekt text. Der Semikolon-Separator wird der Split-Methode als Argument übergeben. In den einzelnen Elementen des String-Arrays liegen danach alle Teilzeichenfolgen vor, die in einer Schleife der Reihe nach an der Konsole angezeigt werden. Nun wollen wir die Methode testen und entwickeln dazu ein kleines Beispielprogramm:
    static void Main(string[] args) {
      string[] str = new String[4];
      str[0] = "Busch;";
      str[1] = "Fridolin;";
      str[2] = "Schlauberger Gasse 12;";
      str[3] = "München";
      string strArr;
      strArr = string.Concat(str);
      GetSubstrings(strArr);
      Console.ReadLine();
    }
Der Konvention folgend, ist bis auf die Angabe des Wohnortes hinter jedem String ein Strichpunkt als Abschluss gesetzt. Jeder String wird als Element eines Arrays gespeichert. Um aus allen Teilstrings einen einzigen zu erstellen, könnten wir mit dem +-Operator arbeiten, aber die Klasse String bietet uns eine Alternative in Form der Methode Concat an, die dazu dient, aus mehreren Einzelstrings einen einzigen Gesamtstring zu erzeugen. Concat ist überladen, um den vielfältigen Anforderungen gerecht zu werden, die sich bei der String-Verknüpfung ergeben. Im Beispielcode fiel die Entscheidung auf die überladene Methode, die als Argument ein String-Array erwartet und aus allen Array-Elementen einen einzigen String formuliert, der unserer benutzerdefinierten Methode GetSubstrings übergeben wird. Die Ausgabe an der Konsole beweist die korrekte Interpretation: Der übergebene String wird wieder in seine ursprünglichen Substrings zerlegt. Beachten Sie, dass die Split-Methode die Trennzeichen im String erkennt und weiß, dass diese nicht zu den einzelnen String-Objekten gehören. Sie werden deshalb automatisch entfernt. #### Zeichenfolgen und »char«-Arrays Sie werden, wenn Sie sich intensiver mit den Klassen des .NET Frameworks beschäftigen, immer wieder auf Methoden treffen, die Parameter entweder vom Typ eines char-Arrays oder vom Typ string deklarieren. Je nach Ausgangssituation im Programm ist dann die Umwandlung eines char-Arrays in string oder umgekehrt notwendig. Möchten Sie aus einem char-Array einen String erzeugen, übergeben Sie dem passenden string-Konstruktor die Referenz auf das Array, beispielsweise:
    char[] charArr = {'K','a','r','n','e','v','a','l'};
    string str;
    str = new string(charArr);
Der umgekehrte Weg, die einzelnen Zeichen einer string-Referenz in ein char-Array zu schreiben, scheint ein wenig kniffliger zu sein. Mit den bisher gezeigten Methoden der Klasse String sollte das kein allzu großes Problem sein, aber die .NET-Baumeister haben Ihnen diese Arbeit bereits abgenommen, wie ein Blick in die Dokumentation der String-Klasse verrät. Diese veröffentlicht die Methode ToCharArray:
    public char[] ToCharArray();
    public char[] ToCharArray(int, int);
Entscheiden Sie sich für die parameterlose Methode, werden die Zeichen des gesamten Strings, auf dem die Methode aufgerufen wird, einem char-Array zugewiesen. Wollen Sie ab einer bestimmten Position einen Teil des Strings einem char-Array zuweisen, entscheiden Sie sich für die parametrisierte ToCharArray-Methode. Das folgende Codefragment benutzt die parameterlose Methode, um das Array zu füllen und anschließend die einzelnen Elemente zeilenweise an der Konsole auszugeben:
    string strText = "Quantenmechanik";
    char[] myCharArr = strText.ToCharArray();
    for(int i = 0; i<= myCharArr.GetUpperBound(0); i++)
       Console.WriteLine(myCharArr[i]);
An der Konsole wird das Wort, das ursprünglich durch einen String gebildet wurde, nun Buchstabe für Buchstabe in je einer Zeile angezeigt. ### 14.2.4 Zusammenfassung der Klasse »String« Zum Abschluss unserer Betrachtungen der Klasse String liste ich des besseren Gesamtüberblicks wegen in tabellarischer Form noch einmal alle in diesem Abschnitt erwähnten Methoden auf.

Tabelle 14.5 Übersicht über die Methoden der Klasse »String«

Methode | Beschreibung
Compare | (Klassenmethode) Vergleicht zwei String-Objekte und liefert einen booleschen Wert zurück.
CompareOrdinal | Vergleicht zwei String-Objekte. Dabei wird der ANSI-Code berücksichtigt.
CompareTo | Wie Compare, jedoch als Instanzmethode implementiert
EndsWith | Prüft, ob das Ende eines gegebenen String-Objekts einer bestimmten Zeichenfolge entspricht.
IndexOf | Liefert den Index des ersten Auftretens einer bestimmten Zeichenfolge oder eines bestimmten char-Typs in einer Zeichenfolge zurück.
IndexOfAny | Liefert den Index des ersten Auftretens eines bestimmten char-Arrays in einer Zeichenfolge zurück.
Insert | Fügt eine Zeichenfolge ab einer bestimmten Position in eine Zeichenfolge ein.
LastIndexOf | Liefert den Index des letzten Auftretens einer bestimmten Zeichenfolge oder char-Typs in einer Zeichenfolge.
PadLeft | Fügt eine bestimmte Anzahl gleicher Zeichen vor dem ersten Zeichen des String-Objekts ein.
PadRight | Fügt eine bestimmte Anzahl gleicher Zeichen nach dem letzten Zeichen des String-Objekts ein.
Remove | Löscht eine Anzahl von Zeichen ab einer spezifizierten Position aus der Zeichenfolge.
Replace | Ersetzt eine Anzahl von Zeichen in einer Zeichenfolge.
Split | Erzeugt aus einer Zeichenfolge mehrere Teilzeichenfolgen mit einem spezifizierten Separator.
StartsWith | Prüft, ob der Anfang eines gegebenen String-Objekts einer bestimmten Zeichenfolge entspricht.
Substring | Liefert eine Zeichenfolge bestimmter Größe aus einem String-Objekt zurück.
ToCharArray | Weist die Zeichen eines String-Objekts einem char-Array zu.
ToLower | Konvertiert alle Zeichen eines Strings in Kleinbuchstaben.
ToUpper | Konvertiert alle Zeichen eines Strings in Großbuchstaben.
Trim | Löscht alle voraus- oder nachlaufenden Leerzeichen einer Zeichenfolge.
Anmerkung
In vielen Situationen mögen die von der Klasse zur Verfügung gestellten Methoden nicht ausreichen, um die Anforderungen an eine spezifische Software abzudecken. Die Klasse String ist zudem als sealed deklariert, sodass sich anscheinend keine Möglichkeit bietet, hier durch Vererbung eine Anpassung an die Erfordernisse vorzunehmen. Seit dem .NET Framework 3.5 und der Einführung der Erweiterungsmethoden hat sich das jedoch grundsätzlich geändert Sie können nun auch die Klasse String an Ihre Bedürfnisse durch Ergänzung um zusätzliche Methoden anpassen. Mehr über Erweiterungsmethoden finden Sie in Abschnitt 7.5.