Was ist der Unterschied zwischen einer veränderlichen und einer unveränderlichen Zeichenfolge in C #?
Was ist der Unterschied zwischen einer veränderlichen und einer unveränderlichen Zeichenfolge in C #?
Antworten:
Veränderlich und unveränderlich sind englische Wörter, die "können sich ändern" bzw. "können sich nicht ändern" bedeuten. Die Bedeutung der Wörter ist im IT-Kontext dieselbe. dh
Die Bedeutungen dieser Wörter sind in C # / .NET dieselben wie in anderen Programmiersprachen / -umgebungen, obwohl (offensichtlich) die Namen der Typen und andere Details unterschiedlich sein können.
Für die Aufzeichnung:
String
ist der Standardtyp für unveränderliche C # / .Net-Zeichenfolgen StringBuilder
ist der standardmäßige veränderbare C # / .Net-Zeichenfolgentyp Um eine Änderung an einer als C # dargestellten Zeichenfolge "vorzunehmen" String
, erstellen Sie tatsächlich ein neues String
Objekt. Das Original String
wird nicht verändert ... weil es unveränderlich ist.
In den meisten Fällen ist es besser zu verwenden, String
weil es einfacher ist, sie zu verstehen. Sie müssen beispielsweise nicht die Möglichkeit in Betracht ziehen, dass ein anderer Thread "meine Zeichenfolge ändert". Wenn Sie jedoch eine Zeichenfolge mithilfe einer Folge von Operationen erstellen oder ändern müssen, ist die Verwendung von a möglicherweise effizienter StringBuilder
.
Und schließlich beschreibt StringBuilder
die Microsoft- Dokumentation für diejenigen, die behaupten, dass a keine Zeichenfolge ist, weil es nicht unveränderlich ist, Folgendes StringBuilder
:
"Stellt eine veränderbare Zeichenfolge dar . Diese Klasse kann nicht vererbt werden."
String
ist unveränderlich
dh Strings können nicht geändert werden. Wenn Sie eine Zeichenfolge ändern (indem Sie sie beispielsweise hinzufügen), erstellen Sie tatsächlich eine neue Zeichenfolge.
Ist StringBuilder
aber nicht unveränderlich (vielmehr ist es veränderlich)
Wenn Sie also eine Zeichenfolge mehrmals ändern müssen, z. B. mehrere Verkettungen, verwenden Sie StringBuilder
.
O(N^2)
Verhalten ...
Ein Objekt kann geändert werden, wenn sein Status nach seiner Erstellung durch Aufrufen verschiedener Operationen geändert werden kann. Andernfalls ist es unveränderlich.
In C # (und .NET) wird eine Zeichenfolge durch die Klasse System.String dargestellt. Das string
Schlüsselwort ist ein Alias für diese Klasse.
Die System.String-Klasse ist unveränderlich, dh sobald sie erstellt wurde, kann ihr Status nicht mehr geändert werden .
So sind alle Operationen , die an einer Schnur wie Substring
, Remove
, Replace
, Verkettung mit ‚+‘ Operator usw. wird eine neue Zeichenfolge erstellen und es zurück.
Demonstrieren Sie das folgende Programm -
string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);
Dadurch werden "string" bzw. "mystring" gedruckt.
Für die Vorteile der Unveränderlichkeit und warum Zeichenfolgen unveränderlich sind, überprüfen Sie, warum .NET- Zeichenfolgen unveränderlich sind. .
Wenn Sie eine Zeichenfolge haben möchten, die Sie häufig ändern möchten, können Sie die StringBuilder
Klasse verwenden. Operationen an einer StringBuilder
Instanz ändern dasselbe Objekt .
Weitere Hinweise zur Verwendung finden Sie StringBuilder
unter Wann wird StringBuilder verwendet? .
Alle string
Objekte sind in C # unveränderlich. string
Einmal erstellte Objekte der Klasse können niemals einen anderen Wert als den darstellen, mit dem sie erstellt wurden. Alle Operationen, die eine Zeichenfolge zu "ändern" scheinen, erzeugen stattdessen eine neue. Dies ist ineffizient mit dem Speicher, aber äußerst nützlich, um darauf vertrauen zu können, dass sich die Form einer Zeichenfolge unter Ihnen nicht ändert. Solange Sie Ihre Referenz nicht ändern, ändert sich die Zeichenfolge, auf die verwiesen wird, niemals.
Ein veränderliches Objekt verfügt dagegen über Datenfelder, die geändert werden können. Eine oder mehrere seiner Methoden ändern den Inhalt des Objekts oder haben eine Eigenschaft, die beim Schreiben den Wert des Objekts ändert.
Wenn Sie ein veränderbares Objekt haben - das String am ähnlichsten ist StringBuffer
-, müssen Sie eine Kopie davon erstellen, wenn Sie absolut sicher sein möchten, dass es sich nicht unter Ihnen ändert. Aus diesem Grund ist es gefährlich, veränderbare Objekte als Schlüssel für jede Form Dictionary
oder Menge zu verwenden. Die Objekte selbst können sich ändern, und die Datenstruktur kann nicht erkannt werden, was zu beschädigten Daten führt, die Ihr Programm schließlich zum Absturz bringen würden.
Sie können jedoch den Inhalt ändern. Dies ist viel, viel speichereffizienter als das Erstellen einer vollständigen Kopie, da Sie ein einzelnes Zeichen oder ähnliches ändern möchten.
Im Allgemeinen ist es richtig, veränderbare Objekte zu verwenden, während Sie etwas erstellen, und unveränderliche Objekte, wenn Sie fertig sind. Dies gilt natürlich für Objekte mit unveränderlichen Formen; Die meisten Sammlungen tun dies nicht. Es ist jedoch oft nützlich, schreibgeschützte Formen von Sammlungen bereitzustellen, was unveränderlich ist, wenn der interne Status Ihrer Sammlung an andere Kontexte gesendet wird. Andernfalls kann etwas diesen Rückgabewert annehmen, etwas dagegen tun und Ihre beschädigen Daten.
Unveränderlich:
Wenn Sie eine Operation an einem Objekt ausführen, wird ein neues Objekt erstellt, sodass der Status nicht wie im Fall einer Zeichenfolge geändert werden kann.
Veränderlich
Wenn Sie eine Operation an einem Objekt ausführen, hat das Objekt selbst kein neues Objekt geändert, das wie im Fall von StringBuilder erstellt wurde
In .NET ist System.String (auch bekannt als Zeichenfolge) ein unveränderliches Objekt. Das heißt, wenn Sie ein Objekt erstellen, können Sie dessen Wert danach nicht mehr ändern. Sie können nur ein unveränderliches Objekt neu erstellen.
System.Text.StringBuilder ist ein veränderbares Äquivalent zu System.String, und Sie können seinen Wert ändern
Beispielsweise:
class Program
{
static void Main(string[] args)
{
System.String str = "inital value";
str = "\nsecond value";
str = "\nthird value";
StringBuilder sb = new StringBuilder();
sb.Append("initial value");
sb.AppendLine("second value");
sb.AppendLine("third value");
}
}
Erzeugt folgende MSIL: Wenn Sie den Code untersuchen. Sie werden sehen, dass Sie jedes Mal, wenn Sie ein Objekt von System.String ändern, tatsächlich ein neues erstellen. In System.Text.StringBuilder wird das Objekt jedoch nicht neu erstellt, wenn Sie den Wert von Text ändern.
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 62 (0x3e)
.maxstack 2
.locals init ([0] string str,
[1] class [mscorlib]System.Text.StringBuilder sb)
IL_0000: nop
IL_0001: ldstr "inital value"
IL_0006: stloc.0
IL_0007: ldstr "\nsecond value"
IL_000c: stloc.0
IL_000d: ldstr "\nthird value"
IL_0012: stloc.0
IL_0013: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
IL_0018: stloc.1
IL_0019: ldloc.1
IL_001a: ldstr "initial value"
IL_001f: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::Append(string)
IL_0024: pop
IL_0025: ldloc.1
IL_0026: ldstr "second value"
IL_002b: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendLine(string)
IL_0030: pop
IL_0031: ldloc.1
IL_0032: ldstr "third value"
IL_0037: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendLine(string)
IL_003c: pop
IL_003d: ret
} // end of method Program::Main
Zeichenfolgen sind veränderbar, da .NET hinter den Kulissen einen Zeichenfolgenpool verwendet. Es bedeutet :
string name = "My Country";
string name2 = "My Country";
Sowohl name als auch name2 beziehen sich auf denselben Speicherort aus dem Zeichenfolgenpool. Angenommen, Sie möchten name2 in Folgendes ändern:
name2 = "My Loving Country";
Es wird im Zeichenfolgenpool nach der Zeichenfolge "My Loving Country" gesucht. Wenn sie gefunden wird, erhalten Sie die Referenz. Eine andere neue Zeichenfolge "My Loving Country" wird im Zeichenfolgenpool erstellt und name2 erhält eine Referenz davon. Aber dieser ganze Prozess " Mein Land " wurde nicht geändert, weil andere Variablen wie der Name ihn noch verwenden. Und das ist der Grund, warum Zeichenfolgen IMMUTIERBAR sind .
StringBuilder funktioniert anders und verwendet keinen String-Pool. Wenn wir eine Instanz von StringBuilder erstellen:
var address = new StringBuilder(500);
Es weist dieser Instanz einen Speicherblock mit einer Größe von 500 Byte zu, und alle Vorgänge ändern lediglich diesen Speicherort und diesen Speicher, der nicht mit einem anderen Objekt geteilt wird. Und das ist der Grund , warum Stringbuilder ist Veraenderlich .
Ich hoffe es wird helfen.
Eigentlich keine. Die String-Klasse ist veränderbar.
unsafe
{
string foo = string.Copy("I am immutable.");
fixed (char* pChar = foo)
{
char* pFoo = pChar;
pFoo[5] = ' ';
pFoo[6] = ' ';
}
Console.WriteLine(foo); // "I am mutable."
}
Diese Art von Logik wird tatsächlich die ganze Zeit in den Klassen String und StringBuilder ausgeführt. Sie weisen einfach jedes Mal eine neue Zeichenfolge zu, wenn Sie Concat, Substring usw. aufrufen, und verwenden Zeigerarithmetik, um in die neue Zeichenfolge zu kopieren. Saiten mutieren einfach nicht selbst, weshalb sie als "unveränderlich" gelten.
Versuchen Sie dies übrigens nicht mit String-Literalen, da Sie sonst Ihr Programm durcheinander bringen:
string bar = "I am a string.";
fixed (char* pChar = bar)
{
char* pBar = pChar;
pBar[2] = ' ';
}
string baz = "I am a string.";
Console.WriteLine(baz); // "I m a string."
Dies liegt daran, dass Zeichenfolgenliterale im Desktop .NET Framework interniert sind. Mit anderen Worten, bar
und baz
zeigen Sie auf genau dieselbe Zeichenfolge. Wenn Sie also eine mutieren, wird die andere mutiert. Dies ist jedoch alles in Ordnung, wenn Sie eine nicht verwaltete Plattform wie WinRT verwenden, auf der es an String-Internierung mangelt.
Zur Verdeutlichung gibt es in C # (oder .NET im Allgemeinen) keine veränderbare Zeichenfolge. Andere Sprachen unterstützen veränderbare Zeichenfolgen (Zeichenfolgen, die sich ändern können), das .NET-Framework jedoch nicht.
Die richtige Antwort auf Ihre Frage lautet also: ALLE Zeichenfolgen sind in C # unveränderlich.
Zeichenfolge hat eine bestimmte Bedeutung. Das Schlüsselwort "string" in Kleinbuchstaben ist lediglich eine Verknüpfung für ein Objekt, das aus der System.String-Klasse instanziiert wurde. Alle aus der Zeichenfolgenklasse erstellten Objekte sind IMMER unveränderlich.
Wenn Sie eine veränderbare Darstellung von Text wünschen, müssen Sie eine andere Klasse wie StringBuilder verwenden. Mit StringBuilder können Sie iterativ eine Sammlung von 'Wörtern' erstellen und diese dann in eine Zeichenfolge konvertieren (wieder unveränderlich).
StringBuilder
widerspricht dem: siehe msdn.microsoft.com/en-us/library/…
Der Datenwert darf nicht geändert werden. Hinweis: Der Variablenwert kann geändert werden, der ursprüngliche unveränderliche Datenwert wurde jedoch verworfen und ein neuer Datenwert im Speicher erstellt.
Von http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/
Kurze Antwort: String ist unveränderlich - während StringBuilder veränderlich ist.
Was bedeutet das ? Das Wiki sagt: Im objektorientierten ist ein unveränderliches Objekt ein Objekt, dessen Status nach seiner Erstellung nicht mehr geändert werden kann. Dies steht im Gegensatz zu einem veränderlichen Objekt, das nach seiner Erstellung geändert werden kann.
Aus der Dokumentation zur StringBuilder-Klasse:
Das String-Objekt ist unveränderlich. Jedes Mal, wenn Sie eine der Methoden in der System.String-Klasse verwenden, erstellen Sie ein neues Zeichenfolgenobjekt im Speicher, für das eine neue Speicherplatzzuweisung für dieses neue Objekt erforderlich ist.
In Situationen, in denen Sie wiederholt Änderungen an einer Zeichenfolge vornehmen müssen, kann der mit dem Erstellen eines neuen Zeichenfolgenobjekts verbundene Aufwand kostspielig sein.
Die System.Text.StringBuilder-Klasse kann verwendet werden, wenn Sie eine Zeichenfolge ändern möchten, ohne ein neues Objekt zu erstellen. Die Verwendung der StringBuilder-Klasse kann beispielsweise die Leistung steigern, wenn viele Zeichenfolgen in einer Schleife miteinander verknüpft werden.
Hier ist das Beispiel für den Builder für unveränderliche Zeichenfolgen und veränderbare Zeichenfolgen
Console.WriteLine("Mutable String Builder");
Console.WriteLine("....................................");
Console.WriteLine();
StringBuilder sb = new StringBuilder("Very Good Morning");
Console.WriteLine(sb.ToString());
sb.Remove(0, 5);
Console.WriteLine(sb.ToString());
Console.WriteLine();
Console.WriteLine("Immutable String");
Console.WriteLine("....................................");
Console.WriteLine();
string s = "Very Good Morning";
Console.WriteLine(s);
s.Substring(0, 5);
Console.WriteLine(s);
Console.ReadLine();
String in C # ist unveränderlich. Wenn Sie es mit einer Zeichenfolge verketten, erstellen Sie tatsächlich eine neue Zeichenfolge, dh ein neues Zeichenfolgenobjekt! StringBuilder erstellt jedoch eine veränderbare Zeichenfolge.
StringBuilder ist eine bessere Option, um eine große Datenzeichenfolge zu verknüpfen, da der StringBuilder ein veränderbarer Zeichenfolgentyp und das StringBuilder-Objekt ein unveränderlicher Typ ist. Dies bedeutet, dass StringBuilder niemals eine neue Objektinstanz erstellt, während die Zeichenfolge verknüpft wird.
Wenn wir String anstelle von StringBuilder verwenden, um eine Verkettung zu erzielen, wird jedes Mal eine neue Instanz im Speicher erstellt.