Laden...
FAQ

[FAQ] Besonderheiten der String-Klasse (immutabler Referenztyp mit Wertsemantik)

Erstellt von herbivore vor 14 Jahren Letzter Beitrag vor 14 Jahren 24.149 Views
herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 14 Jahren
[FAQ] Besonderheiten der String-Klasse (immutabler Referenztyp mit Wertsemantik)

Hallo Community,

die String-Klasse hat einige Besonderheiten, die einen verblüffen oder sogar verwirren können: Deshalb wollen wir diese im Folgenden näher betrachten ...

1. String ist eine Klasse und damit ein Referenztyp

Ob einen das nun verblüfft oder nicht: String ist als class definiert. Jede class ist ein Referenztyp. Also ist String ein Referenztyp. Das bedeutet, dass z.B. bei der Übergabe eines Strings per Parameter an eine Methode und bei Zuweisungen nicht der (Inhalt des) String, sondern nur die Referenz kopiert wird. Allerdings ...

2. String fühlt sich in vielen Aspekten wie ein Werttyp an

Am augenfälligsten ist, dass der Vergleichsoperator (String.operator==) sowie String.Equals den Inhalt (Wert) von zwei Strings vergleichen und nicht deren Referenzen. Auch bei Zuweisungen fühlt sich String wie ein Werttyp an. Bei einer Zuweisung a = b; kann es nicht passieren, dass eine Änderung des Objekts in b nach der Zuweisung auf a durchschlägt, wie das bei Referenztypen üblicherweise der Fall wäre. Das liegt an folgendem ...

3. String-Objekte sind unveränderlich (immutable)

Ein einmal erzeugtes String-Objekt kann nicht mehr geändert werden. Es gibt keine Operation (Methode/Property), die den Inhalt eines bestehenden String-Objekts ändert. Alle Operationen, die inhaltliche Änderungen realisieren, tun das, indem sie ein neues String-Objekt liefern, das das Ergebnis der Änderung enthält. Das alte Objekt existiert aber weiterhin unverändert (bis es ggf. vom GC weggeräumt wird).

Das ist auch der Grund, warum folgender Code nicht funktioniert:


String welcome = "Hello World!";
welcome.Replace ("e", "a");  // unsinnig

Denn String.Replace ändert das Objekt in welcome nicht, sondern liefert als Rückgabewert ein neues String-Objekt mit dem Inhalt "Hallo World!", das aber in dem Codebeispiel ignoriert wird. Richtig wäre also:


String welcome = "Hello World!";
welcome = welcome.Replace ("e", "a"); // sinnvoll

Da das ohne Zweifel etwas umständlicher ist, führt uns das zu der Frage ...

4. Warum sind String-Objekte immutable?

Der Hauptgrund dürfte sein, dass dadurch die Kapselung von Objekten gewahrt wird. Nehmen wir als Beispiel ein Objekt der Klasse Person mit einer String-Property Nachname. Und nehmen wir für einen Moment an, String-Objekte wären änderbar. Wenn man nun ein solches String-Objekt als Nachnamen einer Person setzen würde, dann hätte man ja außerhalb der Person immer noch eine Referenz auf diesen Namen und könnte ihn - unter Verletzung der Kapselung - direkt in dem String-Objekt ändern, ohne dass das Personen-Objekt dagegen etwas machen könnte oder es auch nur mitbekommen würde.

5. Die Klasse String hat keinen parameterlosen Konstruktor

Obwohl sich String in vielerlei Hinsicht wie ein Werttyp anfühlt, ist dies ein Unterschied zu Werttypen, die alle einen parameterlosen Konstruktor haben.

Siehe auch

[Artikel] Performant Strings verketten
[FAQ] Was bedeutet das @ (=at) vor String-Literalen?
myString == "" oder string.Length == 0
String-Klasse und String-Member
StringBuilder-Klasse und StringBuilder-Member

herbivore

PS: Bitte schickt mir weitere erwähnenswerte Besonderheiten per PM.