Qual é a diferença entre uma sequência mutável e imutável em C #?
Qual é a diferença entre uma sequência mutável e imutável em C #?
Respostas:
Mutável e imutável são as palavras em inglês que significam "pode mudar" e "não pode mudar", respectivamente. O significado das palavras é o mesmo no contexto de TI; ie
O significado dessas palavras é o mesmo em C # / .NET e 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 sequência imutável C # / .Net padrão StringBuilder
é o tipo de sequência mutável C # / .Net padrão Para "efetuar uma alteração" em uma sequência representada como C # String
, você realmente cria um novo String
objeto. O original String
não é alterado ... porque é imutável.
Na maioria dos casos, é melhor usar String
porque é uma razão mais fácil sobre eles; por exemplo, você não precisa considerar a possibilidade de que algum outro thread possa "alterar minha string". No entanto, quando você precisa construir ou modificar uma string usando uma sequência de operações, pode ser mais eficiente usar a StringBuilder
.
E, finalmente, para as pessoas que afirmam que a StringBuilder
não é uma sequência porque não é imutável, a documentação da Microsoft descreve StringBuilder
assim:
"Representa uma sequência mutável de caracteres. Esta classe não pode ser herdada."
String
é imutável
isto é, strings não podem ser alteradas. Quando você altera uma sequência (adicionando a ela, por exemplo), na verdade você está criando uma nova sequência.
Mas StringBuilder
não é imutável (é mutável)
portanto, se você precisar alterar uma sequência várias vezes, como várias concatenações, use StringBuilder
.
O(N^2)
comportamento ...
Um objeto é mutável se, uma vez criado, seu estado puder ser alterado chamando várias operações nele, caso contrário, é imutável.
Em C # (e .NET), uma seqüência de caracteres é representada pela classe System.String. A string
palavra-chave é um alias para esta classe.
A classe System.String é imutável, ou seja, uma vez criado, seu estado não pode ser alterado .
Assim, todas as operações que você executar em uma string como Substring
, Remove
, Replace
, concatenação usando operador '+' etc irá criar uma nova seqüência e devolvê-lo.
Veja o seguinte programa para demonstração -
string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);
Isso imprimirá 'string' e 'mystring' respectivamente.
Para os benefícios da imutabilidade e por que a string é imutável, verifique Por que o .NET String é imutável? .
Se você deseja ter uma string que deseja modificar frequentemente, pode usar a StringBuilder
classe As operações em uma StringBuilder
instância modificarão o mesmo objeto .
Para obter mais conselhos sobre quando usar, StringBuilder
consulte Quando usar o StringBuilder? .
Todos os string
objetos são imutáveis em C #. Objetos da classe string
, uma vez criados, nunca podem representar outro valor além daquele com o qual foram construídos. Todas as operações que parecem "alterar" uma sequência produzem uma nova. Isso é ineficiente com a memória, mas extremamente útil em relação à capacidade de confiar que uma string não será alterada sob você - porque, desde que você não altere sua referência, a string a que se refere nunca mudará.
Um objeto mutável, por outro lado, possui campos de dados que podem ser alterados. Um ou mais de seus métodos alteram o conteúdo do objeto ou possuem uma Propriedade que, quando gravada, altera o valor do objeto.
Se você tem um objeto mutável - o mais semelhante a String é StringBuffer
-, é necessário fazer uma cópia dele se quiser ter certeza absoluta de que ele não será alterado. É por isso que objetos mutáveis são perigosos para usar como chaves em qualquer forma Dictionary
ou conjunto - os próprios objetos podem mudar e a estrutura de dados não tem como saber, levando a dados corrompidos que, eventualmente, travariam seu programa.
No entanto, você pode alterar seu conteúdo - portanto, é muito, muito mais eficiente em termos de memória do que fazer uma cópia completa, porque você queria alterar um único caractere ou algo semelhante.
Geralmente, a coisa certa a fazer é usar objetos mutáveis enquanto você cria algo e objetos imutáveis quando terminar. Isso se aplica a objetos que têm formas imutáveis, é claro; a maioria das coleções não. Muitas vezes, é útil fornecer formas de coleções somente leitura, o que equivale a imutável, ao enviar o estado interno da sua coleção para outros contextos; caso contrário, algo pode levar esse valor de retorno, fazer alguma coisa e corromper seu dados.
Imutável:
Quando você faz alguma operação em um objeto, ele cria um novo objeto, portanto, o estado não é modificável, como no caso de uma string.
Mutável
Quando você executa alguma operação em um objeto, o próprio objeto não modifica nenhum novo objeto criado, como no caso de StringBuilder
No .NET System.String (aka string) é um objeto imutável. Isso significa que quando você cria um objeto, não é possível alterar seu valor posteriormente. Você só pode recriar um objeto imutável.
System.Text.StringBuilder é equivalente mutável de System.String e você pode alterar 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 criar um objeto de System.String, estará criando um novo. Mas no System.Text.StringBuilder sempre que você altera o valor do texto, você não recria o objeto.
.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
As strings são mutáveis porque o .NET usa o pool de strings nos bastidores. Isso significa :
string name = "My Country";
string name2 = "My Country";
O nome e o nome2 estão se referindo ao mesmo local de memória do conjunto de cadeias. Agora, suponha que você queira alterar o nome2 para:
name2 = "My Loving Country";
Ele procurará no conjunto de strings a sequência "My Loving Country"; se encontrado, você obterá a referência dela; outra nova sequência sábia "My Loving Country" será criada no pool de strings e name2 obterá referência. Mas todo esse processo " Meu país " não foi alterado porque outra variável como nome ainda o está usando. E essa é a razão pela qual a sequência é IMMUTABLE .
StringBuilder funciona de maneira diferente e não usa pool de strings. Quando criamos qualquer instância do StringBuilder:
var address = new StringBuilder(500);
Ele aloca um pedaço de memória de tamanho 500 bytes para esta instância e todas as operações apenas modificam esse local de memória e essa memória não é compartilhada com nenhum outro objeto. E essa é a razão pela qual StringBuilder é MUTABLE .
Eu espero que isso ajude.
Nenhuma, na verdade. A classe 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 classes String e StringBuilder, na verdade. Eles apenas alocam uma nova string sempre que você chama Concat, Substring, etc. e usam a aritmética do ponteiro para copiar para a nova string. As strings simplesmente não se transformam, por isso são consideradas "imutáveis".
A propósito, não tente fazer isso com literais de string ou você estragará 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 m a 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
aponte para exatamente a mesma string, portanto, uma mutação mutará a outra. Tudo isso é ótimo 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). Outros idiomas suportam seqüências de caracteres mutáveis (sequência que pode ser alterada), mas a estrutura .NET não.
Portanto, a resposta correta para sua pergunta é que TODAS as strings são imutáveis em C #.
string tem um significado específico. A palavra-chave minúscula "string" é apenas um atalho para um objeto instanciado da classe System.String. Todos os objetos criados a partir da classe string são SEMPRE imutáveis.
Se você deseja uma representação mutável do texto, precisará usar outra classe como StringBuilder. O StringBuilder permite criar iterativamente uma coleção de 'palavras' e depois convertê-lo em uma string (mais uma vez imutável).
StringBuilder
contradiz isso: consulte msdn.microsoft.com/en-us/library/…
O valor dos dados não pode ser alterado. Nota: O valor da variável pode ser alterado, mas o valor original dos dados imutáveis foi descartado e um novo valor de dados foi criado na memória.
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 ? O Wiki diz: No orientado a objetos, um objeto imutável é um objeto cujo estado não pode ser modificado após a criação. Isso contrasta com um objeto mutável, que pode ser modificado após a criação.
Na documentação da classe StringBuilder:
O objeto String é imutável. Sempre que você usa um dos métodos da classe System.String, cria um novo objeto de seqüência de caracteres na memória, o que requer uma nova alocação de espaço para esse novo objeto.
Nas situações em que você precisa executar modificações repetidas em uma string, a sobrecarga associada à criação de um novo objeto String pode ser cara.
A classe System.Text.StringBuilder pode ser usada quando você deseja modificar uma seqüência de caracteres sem criar um novo objeto. Por exemplo, o uso da classe StringBuilder pode aumentar o desempenho ao concatenar várias seqüências juntas em um loop.
Aqui está o exemplo para o Construtor de Sequências Imutáveis e Mutáveis
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 em C # é imutável. Se você concatená-lo com qualquer string, na verdade você está criando uma nova string, que é um novo objeto de string! Mas StringBuilder cria uma sequência mutável.
StringBuilder é uma opção melhor para concaturar uma enorme sequência de dados, porque o StringBuilder é um tipo de sequência mutável e o objeto StringBuilder é um tipo imutável, o que significa que o StringBuilder nunca cria uma nova instância do objeto enquanto concata a sequência.
Se estivermos usando string em vez de StringBuilder para obter concatenação, ele criará sempre uma nova instância na memória.