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
uma string mutável pode ser alterada e
uma sequência imutável não pode ser alterada.
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 Stringobjeto. O original Stringnão é alterado ... porque é imutável.
Na maioria dos casos, é melhor usar Stringporque é 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 StringBuildernão é uma sequência porque não é imutável, a documentação da Microsoft descreve StringBuilderassim:
"Representa uma sequência mutável de caracteres. Esta classe não pode ser herdada."
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 StringBuildernão é imutável (é mutável)
portanto, se você precisar alterar uma sequência várias vezes, como várias concatenações, use StringBuilder.
O que acontece se você concatenar seqüências imutáveis muitas vezes? Cargas de uso de memória para seqüências de caracteres sem referências? Ou apenas devagar?
quer
13
@ Rudie - ambos. Cada concatenação cria um novo objeto String e copia todos os caracteres das duas seqüências de entrada. Leva ao O(N^2)comportamento ...
Stephen C
@StephenC explicou com as palavras-chave.
Kent Liau
6
se você tiver que alterar uma string muitas vezes, como várias concatenações, em seguida, usar StringBuilder ... Isso clareou minha mente totalmente obrigado ...
katmanco
45
Um objeto é mutável se, uma vez criado, seu estado puder ser alterado chamando várias operações nele, caso contrário, é imutável.
String imutável
Em C # (e .NET), uma seqüência de caracteres é representada pela classe System.String. A stringpalavra-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.
Se você deseja ter uma string que deseja modificar frequentemente, pode usar a StringBuilderclasse As operações em uma StringBuilderinstância modificarão o mesmo objeto .
Todos os stringobjetos 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 Dictionaryou 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.
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
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.
Ummm ... esse código desmontado mostra apenas que as atribuições do ponteiro estão sendo feitas e os métodos estão sendo chamados. Não tem (quase) nada a ver com mutável versus imutável. (Ele me escapa por que algumas pessoas pensam que desmontar alguns códigos de exemplo irrelevante vai ajudar as pessoas a entender esse tipo de coisa Para começar, a maioria dos programadores não são fluentes em código CLI..)
Stephen C
6
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 =newStringBuilder(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 .
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, bare bazaponte 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.
Bem, sim. Se você quebrar as regras quebrando abstrações abertas que deveriam ser fechadas, quase nada será imutável. Você pode fazer coisas análogas em Java usando reflexão desagradável ... mas o JLS afirma que o comportamento que você recebe é indefinido.
Stephen C
2
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).
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.
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 =newStringBuilder("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();
Será muito bom se você pode fornecer a saída bem @Gokul :)
Roy Lee
Substring não altera o valor subjacente. Ele retorna apenas um valor.
Kye 07/07
@Kye e por quê? porque as cordas são :) imutável
LuckyLikey
Seu código de 2 linhas -: s.Substring (0, 5); Console.WriteLine (s); Aqui s.substring () não altera s. este exemplo não mostra se a sequência é imutável.
Dhananjay
0
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.
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ãoStringBuilder
é o tipo de sequência mutável C # / .Net padrãoPara "efetuar uma alteração" em uma sequência representada como C #
String
, você realmente cria um novoString
objeto. O originalString
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 aStringBuilder
.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 descreveStringBuilder
assim:fonte
String
é imutávelisto é, 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
.fonte
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.
String 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 -
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? .
String mutável
Se você deseja ter uma string que deseja modificar frequentemente, pode usar a
StringBuilder
classe As operações em umaStringBuilder
instância modificarão o mesmo objeto .Para obter mais conselhos sobre quando usar,
StringBuilder
consulte Quando usar o StringBuilder? .fonte
Todos os
string
objetos são imutáveis em C #. Objetos da classestring
, 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 formaDictionary
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.
fonte
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
fonte
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:
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.
fonte
As strings são mutáveis porque o .NET usa o pool de strings nos bastidores. Isso significa :
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:
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:
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.
fonte
Nenhuma, na verdade. A classe String é mutável.
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:
Isso ocorre porque literais de seqüência de caracteres são internados no .NET Framework da área de trabalho; em outras palavras,
bar
ebaz
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.fonte
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).
fonte
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.
fonte
em detalhes de implementação.
System.String do CLR2 é mutável. StringBuilder.Append chamando String.AppendInplace (método privado)
O System.String do CLR4 é imutável. StringBuilder tem matriz Char com chunking.
fonte
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.
fonte
Aqui está o exemplo para o Construtor de Sequências Imutáveis e Mutáveis
fonte
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.
fonte
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.
fonte