Qual è la differenza tra una stringa mutabile e immutabile in C #?
Qual è la differenza tra una stringa mutabile e immutabile in C #?
Risposte:
Mutevole e immutabile sono le parole inglesi che significano rispettivamente "può cambiare" e "non può cambiare". Il significato delle parole è lo stesso nel contesto IT; vale a dire
Il significato di queste parole è lo stesso in C # / .NET come in altri linguaggi / ambienti di programmazione, sebbene (ovviamente) i nomi dei tipi possano differire, così come altri dettagli.
Per il record:
String
è il tipo di stringa immutabile standard C # / .Net StringBuilder
è il tipo di stringa mutabile standard C # / .Net Per "effettuare una modifica" su una stringa rappresentata come C # String
, si crea effettivamente un nuovo String
oggetto. L'originale String
non è cambiato ... perché è immutabile.
Nella maggior parte dei casi è meglio usarlo String
perché è una ragione più semplice su di loro; ad esempio non è necessario considerare la possibilità che qualche altro thread possa "cambiare la mia stringa". Tuttavia, quando è necessario costruire o modificare una stringa utilizzando una sequenza di operazioni, potrebbe essere più efficiente utilizzare aStringBuilder
.
E infine, per quelle persone che affermano che a StringBuilder
non è una stringa perché non è immutabile, la documentazione di Microsoft descriveStringBuilder
così:
"Rappresenta una stringa mutabile di caratteri. Questa classe non può essere ereditata."
String
è immutabile
cioè le stringhe non possono essere modificate. Quando modifichi una stringa (aggiungendola ad esempio), stai effettivamente creando una nuova stringa.
Ma StringBuilder
non è immutabile (piuttosto, è mutabile)
quindi se devi modificare una stringa più volte, ad esempio più concatenazioni, usa StringBuilder
.
O(N^2)
comportamento ...
Un oggetto è mutabile se, una volta creato, il suo stato può essere modificato chiamando varie operazioni su di esso, altrimenti è immutabile.
In C # (e .NET) una stringa è rappresentata dalla classe System.String. Ilstring
parola chiave è un alias per questa classe.
La classe System.String è immutabile, ovvero una volta creato il suo stato non può essere modificato .
Quindi, tutte le operazioni si esegue su una stringa come Substring
, Remove
,Replace
, la concatenazione con '+' operatore ecc creerà una nuova stringa e restituirlo.
Vedere il seguente programma per la dimostrazione -
string str = "mystring";
string newString = str.Substring(2);
Console.WriteLine(newString);
Console.WriteLine(str);
Questo stamperà rispettivamente "stringa" e "mystring".
Per i vantaggi dell'immutabilità e perché le stringhe sono immutabili controlla Perché .NET String è immutabile? .
Se vuoi avere una stringa che vuoi modificare spesso puoi usare la StringBuilder
classe. Le operazioni su StringBuilder
un'istanza modificheranno lo stesso oggetto .
Per ulteriori consigli su quando utilizzare, StringBuilder
fare riferimento a Quando utilizzare StringBuilder? .
Tutti gli string
oggetti sono immutabili in C #. Gli oggetti della classe string
, una volta creati, non possono mai rappresentare nessun valore diverso da quello con cui sono stati costruiti. Tutte le operazioni che sembrano "cambiare" una stringa invece ne producono una nuova. Questo è inefficiente con la memoria, ma estremamente utile per quanto riguarda la fiducia che una stringa non cambierà forma sotto di te, perché finché non cambi il riferimento, la stringa a cui fai riferimento non cambierà mai.
Un oggetto mutabile, al contrario, ha campi di dati che possono essere modificati. Uno o più dei suoi metodi modificheranno il contenuto dell'oggetto o ha una proprietà che, una volta scritta, cambierà il valore dell'oggetto.
Se hai un oggetto mutevole - il più simile a String è StringBuffer
- allora devi crearne una copia se vuoi essere assolutamente sicuro che non cambierà da sotto di te. Questo è il motivo per cui gli oggetti mutabili sono pericolosi da usare come chiavi in qualsiasi forma diDictionary
o insieme: gli oggetti stessi potrebbero cambiare e la struttura dei dati non avrebbe modo di saperlo, portando a dati corrotti che, alla fine, potrebbero causare l'arresto anomalo del programma.
Tuttavia, puoi modificarne il contenuto, quindi è molto, molto più efficiente della memoria rispetto alla creazione di una copia completa perché volevi cambiare un singolo personaggio o qualcosa di simile.
Generalmente, la cosa giusta da fare è usare oggetti mutabili mentre stai creando qualcosa e oggetti immutabili una volta che hai finito. Questo vale per gli oggetti che hanno forme immutabili, ovviamente; la maggior parte delle collezioni no. Tuttavia, è spesso utile fornire forme di raccolte di sola lettura, che è l'equivalente di immutabile, quando si invia lo stato interno della raccolta in altri contesti, altrimenti qualcosa potrebbe prendere quel valore di ritorno, fare qualcosa e corrompere il tuo dati.
Immutabile:
Quando si esegue un'operazione su un oggetto, viene creato un nuovo oggetto, pertanto lo stato non è modificabile come nel caso della stringa.
Mutevole
Quando si esegue un'operazione su un oggetto, l'oggetto stesso non ha modificato alcun nuovo oggetto creato come nel caso di StringBuilder
In .NET System.String (aka string) è un oggetto immutabile. Ciò significa che quando si crea un oggetto non è possibile modificarne il valore in seguito. Puoi solo ricreare un oggetto immutabile.
System.Text.StringBuilder è equivalente mutabile di System.String e puoi modificarne il valore
Per esempio:
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");
}
}
Genera la seguente MSIL: se si analizza il codice. Vedrai che ogni volta che cambi un oggetto di System.String, ne stai effettivamente creando uno nuovo. Ma in System.Text.StringBuilder ogni volta che si modifica il valore del testo non si ricrea l'oggetto.
.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
Le stringhe sono modificabili perché .NET utilizza un pool di stringhe dietro la scena. Significa :
string name = "My Country";
string name2 = "My Country";
Sia name che name2 si riferiscono alla stessa posizione di memoria dal pool di stringhe. Supponiamo ora di voler cambiare nome2 in:
name2 = "My Loving Country";
Cercherà nel pool di stringhe la stringa "My Loving Country", se trovato ne otterrai il riferimento. Un'altra nuova saggia stringa "My Loving Country" verrà creata nel pool di stringhe e name2 ne farà riferimento. Ma l'intero processo " My Country " non è stato modificato perché è ancora utilizzato da un'altra variabile come il nome . E questo è il motivo per cui le stringhe sono IMMUTABILI .
StringBuilder funziona in modo diverso e non utilizza il pool di stringhe. Quando creiamo qualsiasi istanza di StringBuilder:
var address = new StringBuilder(500);
Alloca spazio di memoria di dimensioni di 500 byte per questa istanza e tutte le operazioni modificano semplicemente questa posizione di memoria e questa memoria non condivisa con nessun altro oggetto. E questo è il motivo per cui StringBuilder è MUTABILE .
Spero che sarà di aiuto.
Nessuno, in realtà. La classe String è modificabile.
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."
}
Questo tipo di logica viene eseguita continuamente nelle classi String e StringBuilder, in realtà. Assegnano semplicemente una nuova stringa ogni volta che chiamate Concat, Substring, ecc. E usano l'aritmetica del puntatore per copiare sulla nuova stringa. Le stringhe non si mutano, quindi perché sono considerate "immutabili".
A proposito, non tentare di farlo con valori letterali stringa o potresti incasinare gravemente il tuo programma:
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."
Questo perché i valori letterali delle stringhe sono internati in .NET Framework desktop; in altre parole, bar
e baz
punta esattamente alla stessa stringa, così mutando l'una muterà l'altra. Tutto questo va bene e dandy se stai usando una piattaforma non gestita come WinRT, che manca di interning delle stringhe.
Per chiarire non esiste una stringa mutabile in C # (o .NET in generale). Altre lingue supportano stringhe mutabili (stringa che può cambiare) ma il framework .NET no.
Quindi la risposta corretta alla tua domanda è che TUTTE le stringhe sono immutabili in C #.
stringa ha un significato specifico. La parola chiave "stringa" minuscola è semplicemente una scorciatoia per un oggetto istanziato dalla classe System.String. Tutti gli oggetti creati dalla classe stringa sono SEMPRE immutabili.
Se si desidera una rappresentazione mutevole del testo, è necessario utilizzare un'altra classe come StringBuilder. StringBuilder ti consente di creare iterativamente una raccolta di "parole" e di convertirla in una stringa (ancora una volta immutabile).
StringBuilder
contraddice questo: vedi msdn.microsoft.com/en-us/library/…
Il valore dei dati non può essere modificato. Nota: il valore della variabile può essere modificato, ma il valore dei dati immutabili originale è stato scartato e un nuovo valore di dati è stato creato in memoria.
A partire dal http://yassershaikh.com/what-is-the-difference-between-strings-and-stringbuilder-in-c-net/
Risposta breve: String è immutabile, mentre StringBuilder è modificabile.
Cosa significa ? Wiki dice: In orientato agli oggetti, un oggetto immutabile è un oggetto il cui stato non può essere modificato dopo la sua creazione. Ciò è in contrasto con un oggetto mutabile, che può essere modificato dopo la sua creazione.
Dalla documentazione della classe StringBuilder:
L'oggetto String è immutabile. Ogni volta che si utilizza uno dei metodi nella classe System.String, si crea un nuovo oggetto stringa in memoria, che richiede una nuova allocazione di spazio per quel nuovo oggetto.
In situazioni in cui è necessario eseguire ripetute modifiche a una stringa, l'overhead associato alla creazione di un nuovo oggetto String può essere costoso.
La classe System.Text.StringBuilder può essere utilizzata quando si desidera modificare una stringa senza creare un nuovo oggetto. Ad esempio, l'utilizzo della classe StringBuilder può migliorare le prestazioni quando si concatenano molte stringhe insieme in un ciclo.
Ecco l'esempio per Immutable string e Mutable string builder
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();
La stringa in C # è immutabile. Se lo concateni con qualsiasi stringa, stai effettivamente creando una nuova stringa, ovvero un nuovo oggetto stringa! Ma StringBuilder crea una stringa mutabile.
StringBuilder è un'opzione migliore per concatenare una stringa di dati enorme perché StringBuilder è un tipo di stringa mutabile e l'oggetto StringBuilder è un tipo immutabile, ciò significa che StringBuilder non crea mai una nuova istanza di oggetto mentre concatena la stringa.
Se stiamo usando string anziché StringBuilder per ottenere la concatenazione, creerà ogni volta una nuova istanza in memoria.