Qual é a diferença entre uma string mutável e imutável em c #?

Qual é a diferença entre uma string mutável e imutável em c #?

Mutável e imutável são palavras inglesas que significam “podem mudar” e “não podem mudar” respectivamente. O significado das palavras é o mesmo no contexto de TI; ou seja

  • uma string mutável pode ser alterada e
  • uma string imutável não pode ser alterada.

Os significados dessas palavras são os mesmos em C # / .NET como em outras linguagens / ambientes de programação, embora (obviamente) os nomes dos tipos possam diferir, assim como outros detalhes.


Para o registro:

  • String é o tipo de string imutável C # / .Net padrão
  • StringBuilder é o tipo de cadeia mutável C # / .Net padrão

Para “efetuar uma alteração” em uma string representada como uma C # String , você cria um novo object String . A String original não é alterada … porque é imutável.

Na maioria dos casos, é melhor usar String porque é mais fácil sobre eles; Por exemplo, você não precisa considerar a possibilidade de que algum outro thread possa “mudar minha string”. No entanto, quando você precisa construir ou modificar uma seqüência de caracteres usando uma seqüência de operações, talvez seja mais eficiente usar um StringBuilder .


E finalmente, para aquelas pessoas que afirmam que um StringBuilder não é uma string porque não é imutável, a documentação da Microsoft descreve o StringBuilder assim:

“Representa uma string mutável de caracteres. Esta class não pode ser herdada.”

String é imutável

isto é, as cordas não podem ser alteradas. Quando você altera uma string (adicionando a ela por exemplo), você está criando uma nova string.

Mas o StringBuilder não é imutável (é mutável)

Portanto, se você precisar alterar uma cadeia de caracteres muitas vezes, como várias concatenações, use StringBuilder .

Um object é mutável se, uma vez criado, seu estado puder ser alterado chamando várias operações nele, caso contrário, é imutável.

Corda Imutável

Em C # (e .NET), uma string é representada pela class System.String. A palavra-chave string é um alias para essa class.

A class System.String é imutável, ou seja, uma vez criada, seu estado não pode ser alterado .

Assim, todas as operações que você executa em uma string como Substring, Remove, Replace, Concatenation usando o operador ‘+’ etc. criarão uma nova string e a retornarão.

Veja o seguinte programa para demonstração –

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

Isto irá imprimir ‘string’ e ‘mystring’ respectivamente.

Para os benefícios da imutabilidade e porque as strings são imutáveis, verifique porque o .NET String é imutável? .

Corda Mutável

Se você quiser ter uma string que você deseja modificar com freqüência, você pode usar a class StringBuilder . Operações em uma instância StringBuilder modificarão o mesmo object .

Para obter mais conselhos sobre quando usar o StringBuilder consulte Quando usar o StringBuilder? .

Todos os objects de string são imutáveis ​​em C #. Objetos da class string , uma vez criados, nunca podem representar qualquer valor diferente daquele com o qual foram construídos. Todas as operações que parecem “mudar” uma string, em vez disso, produzem uma nova. Isso é ineficiente com a memory, mas extremamente útil no que diz respeito a ser capaz de confiar que uma string não mudará de forma sob você – porque, desde que você não altere sua referência, a string que está sendo referida nunca mudará.

Um object mutável, ao contrário, possui campos de dados que podem ser alterados. Um ou mais dos seus methods alterarão o conteúdo do object ou uma propriedade que, quando gravada, alterará o valor do object.

Se você tem um object mutável – o mais parecido com o String é o StringBuffer – então você tem que fazer uma cópia dele se quiser ter certeza absoluta de que ele não mudará de você. É por isso que objects mutáveis ​​são perigosos para serem usados ​​como chaves em qualquer forma de Dictionary ou configuração – os próprios objects podem mudar, e a estrutura de dados não teria como saber, levando a dados corrompidos que acabariam por travar seu programa.

No entanto, você pode alterar seu conteúdo – por isso, é muito mais eficiente em termos de memory do que fazer uma cópia completa porque você queria alterar um único caractere ou algo semelhante.

Geralmente, a coisa certa a se fazer é usar objects mutáveis ​​enquanto você cria algo, e objects imutáveis, uma vez que você esteja pronto. Isso se aplica a objects que têm formas imutáveis, é claro; a maioria das collections não. No entanto, é útil fornecer formas de collections somente leitura, o que é equivalente a imutável, ao enviar o estado interno de sua coleção para outros contextos. Caso contrário, algo poderia levar esse valor de retorno, fazer alguma coisa e corromper sua coleção. dados.

Imutável:

Quando você faz alguma operação em um object, ele cria um novo object, portanto, o estado não é modificável como no caso da string.

Mutável

Quando você executa alguma operação em um object, o object em si não modifica nenhum novo obect criado como no caso do StringBuilder

No .NET System.String (string aka) é um object imutável. Isso significa que quando você cria um object, você não pode alterar seu valor depois. Você só pode recriar um object imutável.

System.Text.StringBuilder é equivalente mutável de System.String e você pode cobrar seu valor

Por exemplo:

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

Gera o seguinte MSIL: Se você investigar o código. Você verá que sempre que você usa um object de System.String você está criando um novo. Mas em System.Text.StringBuilder sempre que você altera o valor do texto, não recria o object.

 .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 

Strings são mutáveis ​​porque o .NET usa o pool de strings atrás da cena. Isso significa :

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

Tanto name quanto name2 estão se referindo ao mesmo local de memory do pool de strings. Agora, suponha que você queira mudar o nome2 para:

 name2 = "My Loving Country"; 

Ele vai olhar para string pool para a string “My Loving Country”, se for encontrado, você terá a referência de outra nova string “My Loving Country” será criada no conjunto de strings e name2 receberá uma referência. Mas todo esse processo ” Meu País ” não foi alterado porque outra variável como o nome ainda está usando. E essa é a razão pela qual as sequências são IMUUTÁVEIS .

O StringBuilder funciona de maneira diferente e não usa o pool de strings. Quando criamos qualquer instância de StringBuilder:

 var address = new StringBuilder(500); 

Ele aloca um pedaço de memory de 500 bytes de tamanho para essa instância e toda a operação apenas modifica esse local de memory e essa memory não é compartilhada com nenhum outro object. E essa é a razão pela qual o StringBuilder é MUTABLE .

Eu espero que isso ajude.

Nenhum, na verdade. A class String é mutável.

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

Esse tipo de lógica é feito o tempo todo nas classs String e StringBuilder, na verdade. Eles apenas alocam uma nova string toda vez que você chama Concat, Substring, etc. e usam a aritmética de pointers para copiar para a nova string. As cordas simplesmente não se transformam, daí porque elas são consideradas “imutáveis”.


By the way, não tente isso com literais string ou você vai atrapalhar o seu programa:

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

Isso ocorre porque literais de seqüência de caracteres são internados no .NET Framework da área de trabalho; em outras palavras, bar e baz apontam exatamente para a mesma string, então mutar um irá mudar o outro. Isso tudo é bom e elegante se você estiver usando uma plataforma não gerenciada como o WinRT, que não possui internação de strings.

Para esclarecer, não existe uma string mutável em C # (ou .NET em geral). Outras línguas suportam strings mutáveis ​​(string que pode mudar) mas o .NET framework não.

Então a resposta correta para sua pergunta é que TODAS as seqüências são imutáveis ​​em C #.

string tem um significado específico. A palavra-chave minúscula “string” é meramente um atalho para um object instanciado da class System.String. Todos os objects criados a partir da class de strings são SEMPRE imutáveis.

Se você quer uma representação mutável do texto, então você precisa usar outra class como o StringBuilder. O StringBuilder permite que você construa iterativamente uma coleção de ‘palavras’ e as converta em uma string (mais uma vez imutável).

O valor dos dados não pode ser alterado. Nota: O valor da variável pode ser alterado, mas o valor dos dados imutáveis ​​originais foi descartado e um novo valor de dados foi criado na memory.

em detalhes de implementação.

O System.String do CLR2 é mutável. StringBuilder.Append chamando String.AppendInplace (método privado)

O System.String do CLR4 é imutável. O StringBuilder possui uma matriz Char com chunking.

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

Resposta Curta: String é imutável – enquanto StringBuilder é mutável.

O que isso significa ? Wiki diz: No object orientado, um object imutável é um object cujo estado não pode ser modificado depois de criado. Isso está em contraste com um object mutável, que pode ser modificado depois de criado.

Da documentação da class StringBuilder:

O object String é imutável. Toda vez que você usa um dos methods na class System.String, você cria um novo object de seqüência de caracteres na memory, que requer uma nova alocação de espaço para esse novo object.

Em situações em que você precisa executar modificações repetidas em uma sequência, a sobrecarga associada à criação de um novo object String pode ser dispendiosa.

A class System.Text.StringBuilder pode ser usada quando você deseja modificar uma seqüência de caracteres sem criar um novo object. Por exemplo, o uso da class StringBuilder pode aumentar o desempenho ao concatenar várias cadeias em um loop.

Aqui está o exemplo para a cadeia Immutable e o construtor de string 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(); 

Cadeia em C # é imutável. Se você concatenar com qualquer string, você está realmente criando uma nova string, que é um novo object string! Mas o StringBuilder cria uma string mutável.