Quelqu'un peut-il me dire s'il vous plaît le nombre total d'instances de chaînes créées en mémoire pour l'exemple ci-dessous? Une brève explication serait très appréciée.
Mon code:
String A = "1" + "2" + "3" ; /* total number of strings in memory = ?? */
String B = "1" + "2" + "1" ; /* total number of strings in memory = ?? */
string one = "1";
string two = "2";
string three = "3";
String C = one + two + three; /* total number of strings in memory = ?? */
String D = one + two + one; /* total number of strings in memory = ?? */
Réponses:
4 pour la réponse № 1Du Documentation C # sur la concaténation de chaînes:
Lorsque vous concaténez des littéraux de chaîne ou des constantes de chaîne à l'aide de l'opérateur +, le compilateur crée une seule chaîne. Aucune concaténation à l'exécution ne se produit.
Cela signifie que vos concaténations ne créent qu'une seule chaîne. Par conséquent, votre exemple génère 7 chaînes en mémoire:
String A = "1" + "2" + "3" ; // 1 (concatenation of literals)
String B = "1" + "2" + "1" ; // 1 (concatenation of literals)
string one = "1"; // 1
string two = "2"; // 1
string three = "3"; // 1
String C = one + two + three; // 1 (concatenation of string constants)
String D = one + two + one; // 1 (concatenation of string constants)
// = 7 strings in total
Toutefois, si vous effectuez la concaténation dans une boucle, davantage de chaînes sont générées, par exemple:
for word in text:
result_string += word // Bad! Creates a new string in each iteration
Dans ce cas, il vaut mieux utiliser StringBuilder.append
:
System.Text.StringBuilder builder = new System.Text.StringBuilder();
for word in text:
builder.Append(word) // Good! Just appends to the string builder
3 pour la réponse № 2
Regardons le code IL dans le DASM IL
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 54 (0x36)
.maxstack 3
.locals init ([0] string A,
[1] string B,
[2] string one,
[3] string two,
[4] string three,
[5] string C,
[6] string D)
IL_0000: nop
IL_0001: ldstr "123"
IL_0006: stloc.0
IL_0007: ldstr "121"
IL_000c: stloc.1
IL_000d: ldstr "1"
IL_0012: stloc.2
IL_0013: ldstr "2"
IL_0018: stloc.3
IL_0019: ldstr "3"
IL_001e: stloc.s three
IL_0020: ldloc.2
IL_0021: ldloc.3
IL_0022: ldloc.s three
IL_0024: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_0029: stloc.s C
IL_002b: ldloc.2
IL_002c: ldloc.3
IL_002d: ldloc.2
IL_002e: call string [mscorlib]System.String::Concat(string,
string,
string)
IL_0033: stloc.s D
IL_0035: ret
} // end of method Program::Main
Comme vous pouvez le voir, il y a 5 constantes de chaîne
"123", "121", "1", "2", "3"
et deux chaînes obtenues par concaténation. Total 7.
Bien que les chaînes A et C (B et D) soient identiques, elles sont toutefois différentes en mémoire.
À Arghya C.
Si nous appliquons le code non sécurisé et modifions la valeur de la variable A:
Console.WriteLine(A + " " + C);
fixed (char* p = A)
{
p[1] = "x";
}
Console.WriteLine(A + " " + C);
nous obtenons la sortie suivante:
123 123
1x3 123
Comme vous pouvez le constater, seule la variable A a changé, mais la variable C a conservé sa valeur. Cela prouve qu'il s'agit de copies différentes.
Cependant, si nous écrivons ceci:
String A = "1" + "2" + "3";
String C = "123";
Après avoir exécuté le code non sécurisé ci-dessus, nous obtenons ce qui suit:
123 123
1x3 1x3
Autrement dit, dans ce cas, les variables A et C conservent une référence à la même instance de la chaîne.
Au début, j’écrivais la mauvaise réponse, parce que je pensais que le compilateur était assez intelligent pour comprendre au moment de la compilation String C = one + two + three;
concatène des constantes et créera une référence sur la même chaîne.