/ / Nombre total d'objets de chaîne en mémoire - c #, .net, string

Nombre total d'objets de chaîne en mémoire - c #, .net, string

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 № 1

Du 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.