webentwicklung-frage-antwort-db.com.de

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 #?

185
Venkadesh

Veränderlich und unveränderlich sind englische Wörter, die jeweils "können sich ändern" und "können sich nicht ändern". Die Bedeutung der Wörter ist im IT-Kontext dieselbe. d.h.

  • eine veränderliche Zeichenfolge kann geändert werden
  • eine unveränderliche Zeichenfolge kann nicht geändert werden.

Die Bedeutungen dieser Wörter sind in C #/.NET die gleichen wie in anderen Programmiersprachen umgebungen, obwohl (offensichtlich) die Namen der Typen und andere Details variieren können.


Für das Protokoll:

Um eine Änderung vorzunehmen, die sich auf einen String bezieht, der als C # String dargestellt wird, erstellen Sie ein neues String-Objekt. Das Original String wird nicht geändert, da es nicht veränderbar ist.

In den meisten Fällen ist es besser, String zu verwenden, da dies eine einfachere Begründung ist. z.B. Sie müssen 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 es möglicherweise effizienter, StringBuilder zu verwenden.


Und für diejenigen, die behaupten, dass ein StringBuilder keine Zeichenfolge ist, weil es nicht unveränderlich ist, beschreibt die Microsoft/-DokumentationStringBuilder daher:

"Stellt eine mutable Zeichenfolge von Zeichen dar. Diese Klasse kann nicht vererbt werden."

311
Stephen C

String ist unveränderlich

strings können nicht geändert werden. Wenn Sie eine Zeichenfolge ändern (z. B. durch Hinzufügen), erstellen Sie tatsächlich eine neue Zeichenfolge.

StringBuilder ist jedoch nicht unveränderlich (es ist vielmehr veränderlich)

wenn Sie also eine Zeichenfolge mehrmals ändern müssen, z. B. mehrere Verkettungen, verwenden Sie StringBuilder.

180
Pankaj Agarwal

Ein Objekt ist veränderbar, wenn der Status nach der Erstellung durch Aufrufen verschiedener Operationen für das Objekt geändert werden kann. Andernfalls ist es unveränderlich.

Immutable String

In C # (und .NET) wird eine Zeichenfolge durch die Klasse System.String dargestellt. Das Schlüsselwort string ist ein Alias ​​für diese Klasse. 

Die System.String-Klasse ist unveränderlich, d. H. Nachdem sie einmal erstellt wurde, kann sie nicht mehr geändert werden.

Alle Operationen, die Sie an einer Zeichenfolge wie Substring, Remove, Replace, Verkettung mit dem Operator "+" usw. ausführen, erstellen also eine neue Zeichenfolge und geben diese zurück.

Siehe folgendes Programm zur Demonstration -

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 Zeichenfolge unveränderlich ist Warum ist .NET String unveränderlich? .

Mutable String

Wenn Sie einen String haben möchten, den Sie häufig ändern möchten, können Sie die StringBuilder-Klasse verwenden. Operationen an einerStringBuilderInstanz ändern dasselbe Objekt

Weitere Hinweise zu wann manStringBuilder verwendet, finden Sie unter Wann wird StringBuilder verwendet? .

44

Alle string-Objekte sind in C # unveränderlich. Einmal erstellte Objekte der Klasse string können niemals einen anderen Wert als denjenigen darstellen, mit dem sie erstellt wurden. Alle Operationen, die scheinbar eine Zeichenfolge "ändern", erzeugen stattdessen eine neue. Dies ist in Bezug auf den Arbeitsspeicher ineffizient, aber äußerst nützlich, um darauf zu vertrauen, dass eine Zeichenfolge unter Ihnen nicht die Form ändert. Solange Sie Ihre Referenz nicht ändern, ändert sich die Zeichenfolge, auf die verwiesen wird, nie.

Ein veränderbares Objekt dagegen verfügt über Datenfelder, die geändert werden können. Eine oder mehrere seiner Methoden ändern den Inhalt des Objekts oder es verfügt über eine Eigenschaft, in die der Wert des Objekts geschrieben wird, wenn er in diesen geschrieben wird.

Wenn Sie ein veränderbares Objekt haben - das ähnlichste ist String StringBuffer-, dann müssen Sie eine Kopie davon erstellen, wenn Sie absolut sicher sein wollen, dass es sich nicht von Ihnen unterscheidet. Aus diesem Grund sind veränderliche Objekte gefährlich, wenn sie als Schlüssel für Dictionary oder als Set verwendet werden. Die Objekte selbst können sich ändern, und die Datenstruktur hat keine Möglichkeit zu wissen, was zu fehlerhaften Daten führt, die Ihr Programm letztendlich zum Absturz bringen könnten.

Sie können jedoch den Inhalt ändern - es ist also viel, viel speichereffizienter als das Erstellen einer vollständigen Kopie, weil Sie ein einzelnes Zeichen oder etwas Ähnliches ändern wollten.

Im Allgemeinen ist es das Richtige, veränderliche Objekte zu verwenden, wenn Sie etwas erstellen, und unveränderliche Objekte, wenn Sie fertig sind. Dies gilt natürlich für Objekte, die unveränderliche Formen haben. Die meisten Kollektionen tun dies nicht. Es ist jedoch häufig hilfreich, schreibgeschützte Formulare für Sammlungen bereitzustellen, was dem Äquivalent von unveränderlich entspricht, wenn der interne Status Ihrer Sammlung an andere Kontexte gesendet wird. Andernfalls könnte etwas diesen Rückgabewert erfordern, etwas bewirken und Ihre Daten beschädigen Daten.

36
Adam Norberg

Unveränderlich: 

Wenn Sie einige Operationen an einem Objekt ausführen, wird ein neues Objekt erstellt. Der Zustand kann also nicht wie bei String geändert werden.

Veränderlich 

Wenn Sie einen Vorgang an einem Objekt ausführen, hat das Objekt selbst kein neues Objekt wie bei StringBuilder erstellt

12
TalentTuner

In .NET System.String (auch als Zeichenfolge bezeichnet) ist ein unveränderliches Objekt. Das heißt, wenn Sie ein Objekt erstellen, können Sie den Wert danach nicht mehr ändern. Sie können nur ein unveränderliches Objekt neu erstellen. 

System.Text.StringBuilder ist ein veränderbares Äquivalent von System.String und Sie können den Wert ändern

Zum Beispiel:

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 feststellen, dass Sie jedes Mal, wenn Sie ein Objekt von System.String ändern, tatsächlich ein neues erstellen. In System.Text.StringBuilder erstellen Sie das Objekt jedoch nicht, wenn Sie den Textwert ä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
8
cahit beyaz

Strings sind veränderbar, da .Net String-Pool hinter den Kulissen verwendet. Es bedeutet :

string name = "My Country";
string name2 = "My Country";

Sowohl name als auch name2 beziehen sich auf denselben Speicherort aus dem String-Pool. Angenommen, Sie möchten name2 ändern in:

name2 = "My Loving Country";

Es wird nach dem String "My Loving Country" gesucht. Wenn es gefunden wird, wird der Verweis darauf angezeigt. Andernfalls wird der neue String "My Loving Country" im String-Pool erstellt und name2 wird den Verweis darauf anzeigen. Aber es wurde dieser gesamte Prozess "My Country" nicht geändert, da andere Variablen wie name ihn immer noch verwenden. Und das ist der Grund, warum Zeichenfolgen UNVERÄNDERLICH sind.

StringBuilder funktioniert anders und verwendet keinen String-Pool. Wenn wir eine Instanz von StringBuilder erstellen:

var address  = new StringBuilder(500);

Für diese Instanz wird ein Speicherblock mit einer Größe von 500 Byte zugewiesen, und alle Vorgänge ändern lediglich diesen Speicherort und diesen Speicher, der nicht mit einem anderen Objekt gemeinsam genutzt wird. Und das ist der Grund, warum StringBuilder MUTABLE ist.

Ich hoffe es wird helfen.

6
Rahul Garg

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 eigentlich immer in den Klassen String und StringBuilder ausgeführt. Sie ordnen bei jedem Aufruf von Concat, Substring usw. eine neue Zeichenfolge zu und verwenden die Zeigerarithmetik, um in die neue Zeichenfolge zu kopieren. Strings verändern sich einfach nicht, weshalb sie als "unveränderlich" gelten.


Übrigens, mache nicht versuche dies mit String-Literalen, sonst wirst du dein 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 String-Literale in das .NET-Desktopdesktop integriert sind. Mit anderen Worten, bar und baz zeigen auf genau dieselbe Zeichenfolge, sodass eine mutierende eine die andere mutiert. Dies ist alles in Ordnung, wenn Sie eine nicht verwaltete Plattform wie WinRT verwenden, der String-Interning fehlt.

4
James Ko

Um zu verdeutlichen, gibt es in C # (oder .NET im Allgemeinen) keine veränderliche Zeichenfolge. Andere Sprachen unterstützen veränderliche Zeichenfolgen (Zeichenfolgen, die geändert werden können), .NET Framework jedoch nicht.

Die richtige Antwort auf Ihre Frage lautet also: ALLE Zeichenketten sind in C # unveränderlich.

string hat eine bestimmte Bedeutung. Das Schlüsselwort "string" ist nur eine Abkürzung für ein Objekt, das aus der Klasse System.String instanziiert wird. Alle von der String-Klasse erstellten Objekte sind IMMER unveränderlich.

Wenn Sie eine veränderliche 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).

2
Gerald Davis

im Detail der Implementierung.

CLR2 System.String ist veränderbar. StringBuilder.Append Aufruf von String.AppendInplace (Private Methode)

CLR4 System.String ist unveränderlich. StringBuilder haben Char-Array mit Chunking.

1
kazuk

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 wurde im Speicher erstellt.

1
vikas kumar

Hier ist das Beispiel für den unveränderlichen String und den Builder für veränderbaren String

        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();
0
Gokul

Von http://yassershaikh.com/what-is-the-difference-zwischen -string-und-stringbuilder-in-c-net/

Kurze Antwort: String ist unveränderlich - während StringBuilder veränderbar ist.

Was bedeutet das? Wiki sagt: In objektorientierten Objekten ist ein unveränderliches Objekt ein Objekt, dessen Zustand 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 StringBuilder Class-Dokumentation:

Das String-Objekt ist unveränderlich. Jedes Mal, wenn Sie eine der Methoden in der System.String-Klasse verwenden, erstellen Sie ein neues String-Objekt im Speicher, das eine neue Speicherzuordnung für das neue Objekt erfordert.

In Situationen, in denen Sie wiederholte Änderungen an einer Zeichenfolge vornehmen müssen, kann der mit der Erstellung eines neuen Zeichenfolgeobjekts verbundene Aufwand teuer sein.

Die System.Text.StringBuilder-Klasse kann verwendet werden, wenn Sie eine Zeichenfolge ändern möchten, ohne ein neues Objekt zu erstellen. Durch die Verwendung der StringBuilder-Klasse kann beispielsweise die Leistung gesteigert werden, wenn viele Zeichenfolgen in einer Schleife miteinander verkettet werden.

0
Yasser

Zeichenfolge in C # ist unveränderlich. Wenn Sie es mit einem beliebigen String verketten, erstellen Sie tatsächlich einen neuen String, dh das neue String-Objekt! StringBuilder erstellt jedoch einen veränderbaren String.

0
Md Shahriar