web-dev-qa-db-fra.com

Quelle est la différence entre une chaîne mutable et immuable en C #?

Quelle est la différence entre une chaîne mutable et immuable en C #?

185
Venkadesh

Mutable et immutable sont les mots anglais signifiant "peut changer" et "ne peut pas changer" respectivement. La signification des mots est la même dans le contexte informatique; c'est à dire.

  • une chaîne mutable peut être changée, et
  • une chaîne immuable ne peut pas être changée.

La signification de ces mots est la même en C #/.NET que dans d'autres langages/environnements de programmation, bien que (évidemment) les noms des types puissent différer, de même que d'autres détails.


Pour mémoire:

  • String est le type de chaîne immuable standard C #/.Net 
  • StringBuilder est le type de chaîne mutable standard C #/.Net 

Pour "effectuer un changement" sur une chaîne représentée par une C # String, vous créez en réalité un nouvel objet String. La String d'origine n'est pas modifiée ... car elle ne peut pas être modifiée.

Dans la plupart des cas, il vaut mieux utiliser String car il est plus facile de les expliquer; par exemple. vous n'avez pas besoin de considérer la possibilité qu'un autre thread puisse "changer ma chaîne". Toutefois, lorsque vous devez construire ou modifier une chaîne à l'aide d'une séquence d'opérations, il peut être plus efficace d'utiliser une variable StringBuilder.


Et enfin, pour ceux qui affirment qu'une StringBuilder n'est pas une chaîne car elle n'est pas immuable, la documentation Microsoft documentation décrit StringBuilder ainsi:

"Représente une chaîne mutable de caractères. Cette classe ne peut pas être héritée."

311
Stephen C

String est immuable

c'est-à-dire que les chaînes ne peuvent pas être modifiées. Lorsque vous modifiez une chaîne (en y ajoutant par exemple), vous créez en réalité une nouvelle chaîne.

Mais StringBuilder n'est pas immuable (il est plutôt mutable)

donc si vous devez modifier plusieurs fois une chaîne, telle que plusieurs concaténations, utilisez StringBuilder.

180
Pankaj Agarwal

Un objet est modifiable si, une fois créé, son état peut être modifié en y appelant diverses opérations, sinon il est immuable.

Chaîne immuable

En C # (et .NET), une chaîne est représentée par la classe System.String. Le mot clé string est un alias pour cette classe. 

La la classe System.String est immuable, une fois son état créé ne peut plus être modifié}.

Ainsi, toutes les opérations que vous effectuez sur une chaîne telle que Substring, Remove, Replace, une concaténation à l'aide de l'opérateur '+' etc. créeront une nouvelle chaîne et la retourneront.

Voir le programme suivant pour démonstration -

string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);

Ceci affichera respectivement "chaîne" et "mystère".

Pour les avantages de l'immuabilité} _ et pourquoi les chaînes sont immuables, vérifiez Pourquoi .NET String est immuable? .

Corde Mutable

Si vous souhaitez souvent modifier une chaîne, vous pouvez utiliser la classe StringBuilder. Opérations sur aStringBuilderl'instance modifiera le même objet

Pour plus de conseils sur quand utiliser} _ StringBuilder, reportez-vous à Quand utiliser StringBuilder? .

44
Unmesh Kondolikar

Tous les objets string sont immuables en C #. Une fois créés, les objets de la classe string ne peuvent jamais représenter une valeur autre que celle avec laquelle ils ont été construits. Toutes les opérations qui semblent "changer" une chaîne en produisent une nouvelle. C'est inefficace avec la mémoire, mais extrêmement utile pour pouvoir faire confiance à une chaîne ne changera pas de forme sous votre forme car, tant que vous ne changez pas votre référence, la chaîne à laquelle vous faites référence ne changera jamais.

Un objet mutable, en revanche, possède des champs de données pouvant être modifiés. Une ou plusieurs de ses méthodes modifieront le contenu de l'objet ou une propriété dans laquelle, une fois écrite, modifiera la valeur de l'objet.

Si vous avez un objet mutable (le plus proche de String est StringBuffer), vous devez en faire une copie si vous voulez être absolument sûr qu'il ne changera pas. C'est pourquoi les objets mutables sont dangereux à utiliser comme clés dans toute forme de Dictionary ou ensemble. Les objets eux-mêmes pourraient changer et la structure de données n'aurait aucun moyen de le savoir.

Toutefois, vous pouvez en modifier le contenu. La mémoire est donc beaucoup plus efficace que la copie complète, car vous souhaitez modifier un seul caractère ou quelque chose de similaire.

Généralement, la bonne chose à faire est d'utiliser des objets mutables pendant que vous créez quelque chose, et des objets immuables une fois que vous avez terminé. Ceci s'applique aux objets qui ont des formes immuables, bien sûr; la plupart des collections ne le font pas. Il est souvent utile de fournir des formes de collections en lecture seule, ce qui équivaut à immuable, lorsque vous envoyez l'état interne de votre collection à d'autres contextes. Sinon, quelque chose pourrait prendre cette valeur de retour, faire quelque chose et corrompre votre Les données.

36
Adam Norberg

Immuable: 

Lorsque vous effectuez des opérations sur un objet, un nouvel objet est créé. Par conséquent, l'état n'est pas modifiable, comme dans le cas d'une chaîne.

Mutable 

Lorsque vous effectuez une opération sur un objet, l'objet lui-même ne modifie aucun nouvel objet créé comme dans le cas de StringBuilder.

12
TalentTuner

En .NET System.String (aka string) est un objet immuable. Cela signifie que lorsque vous créez un objet, vous ne pouvez pas modifier sa valeur par la suite. Vous ne pouvez recréer qu'un objet immuable. 

System.Text.StringBuilder est équivalent à System.String et vous pouvez modifier sa valeur.

Par exemple:

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");
    }
}

Génère le MSIL suivant: Si vous étudiez le code. Vous verrez que chaque fois que vous utilisez un objet de System.String, vous en créez un nouveau. Mais dans System.Text.StringBuilder, chaque fois que vous modifiez la valeur du texte, vous ne recréez pas l'objet.

.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

Les chaînes sont modifiables parce que .Net Utilise un pool de chaînes derrière la scène. Ça veut dire :

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

Name et name2 font tous deux référence au même emplacement mémoire depuis le pool de chaînes de caractères . Supposons maintenant que vous souhaitiez remplacer name2 par:

name2 = "My Loving Country";

Il recherchera la chaîne "My Loving Country" dans le pool de chaînes. S'il est trouvé, vous en obtiendrez la référence. La nouvelle chaîne "My Loving Country" sera créée dans le pool de chaînes et name2 en obtiendra la référence .Mais tout ce processus " Mon pays " n'a pas été modifié car une autre variable telle que name l'utilise toujours . Et c'est la raison pour laquelle string estIMMUABLE.

StringBuilder fonctionne de manière différente et n'utilise pas de pool de chaînes. Lorsque nous créons une instance de StringBuilder:

var address  = new StringBuilder(500);

Il alloue une quantité de mémoire de 500 octets pour cette instance et toutes les opérations ne font que modifier cet emplacement mémoire et cette mémoire non partagée avec un autre objet. Et c’est la raison pour laquelle StringBuilder estMUTABLE.

J'espère que cela aidera.

6
Rahul Garg

Aucun, en fait. La classe String est modifiable.

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."
}

Ce genre de logique est fait tout le temps dans les classes String et StringBuilder, en fait. Ils allouent simplement une nouvelle chaîne à chaque fois que vous appelez Concat, Sous-chaîne, etc., et utilisent l'arithmétique de pointeur pour les copier dans la nouvelle chaîne. Les chaînes ne mutent tout simplement pas elles-mêmes, d'où leur désignation comme "immuables".


Au fait, faites pas essayez ceci avec des chaînes de caractères ou vous risquez de gâcher votre programme:

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."

En effet, les littéraux de chaîne sont internés dans le .NET Framework de bureau; En d'autres termes, bar et baz pointent sur la même chaîne exacte, de sorte que mutant mutera l'autre. C’est très bien si vous utilisez une plate-forme non gérée, telle que WinRT, qui manque d’internalisation des chaînes.

4
James Ko

Pour clarifier, il n’existe pas de chaîne mutable en C # (ou .NET en général). D'autres langues prennent en charge les chaînes mutables (chaîne pouvant changer), mais pas le framework .NET.

Donc, la bonne réponse à votre question est que TOUTES les chaînes sont immuables en C #.

chaîne a une signification spécifique. "chaîne" mot-clé minuscule est simplement un raccourci pour un objet instancié à partir de la classe System.String. Tous les objets créés à partir de la classe string sont TOUJOURS immuables.

Si vous voulez une représentation modifiable de texte, vous devez utiliser une autre classe telle que StringBuilder. StringBuilder vous permet de construire de manière itérative une collection de «mots», puis de la convertir en chaîne (encore une fois immuable).

2
Gerald Davis

dans le détail de la mise en œuvre.

La chaîne System.String de CLR2 est modifiable. StringBuilder.Append appelant String.AppendInplace (Méthode privée)

Le System.String de CLR4 est immuable. StringBuilder a un tableau de caractères avec découpage.

1
kazuk

La valeur de données ne peut pas être modifiée. Remarque: La valeur de la variable peut être modifiée, mais la valeur de données immuable d'origine a été ignorée et une nouvelle valeur de données a été créée en mémoire.

1
vikas kumar

Voici l'exemple de la chaîne Immutable et du constructeur de la chaîne Mutable

        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

De http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/

Réponse courte: String est immuable - alors que StringBuilder est modifiable.

Qu'est-ce que cela signifie? Wiki dit: En orienté objet, un objet immuable est un objet dont l'état ne peut pas être modifié après sa création. Cela contraste avec un objet mutable, qui peut être modifié après sa création.

Dans la documentation de la classe StringBuilder:

L'objet String est immuable. Chaque fois que vous utilisez l'une des méthodes de la classe System.String, vous créez un nouvel objet chaîne en mémoire, ce qui nécessite une nouvelle allocation d'espace pour ce nouvel objet.

Dans les cas où vous devez effectuer des modifications répétées sur une chaîne, la surcharge associée à la création d'un nouvel objet String peut être coûteuse.

La classe System.Text.StringBuilder peut être utilisée lorsque vous souhaitez modifier une chaîne sans créer un nouvel objet. Par exemple, l'utilisation de la classe StringBuilder peut améliorer les performances lors de la concaténation de plusieurs chaînes dans une boucle.

0
Yasser

String en C # est immuable. Si vous le concaténez avec une chaîne, vous créez en fait une nouvelle chaîne, c'est-à-dire un nouvel objet chaîne! Mais StringBuilder crée une chaîne mutable.

0
Md Shahriar