L'infrastructure .Net requiert des chaînes d'être immuables. En raison de cette exigence, il est capable d'optimiser toutes sortes d'opérations.
String interning est un bon exemple de cette exigence est fortement exploité. Pour accélérer certaines comparaisons de chaînes (et réduire la consommation de mémoire), le framework .Net maintient un dictionnaire de pointeurs, toutes les chaînes prédéfinies seront dans ce dictionnaire ou dans toutes les chaînes sur lesquelles vous appelez la méthode String.intern
. Lorsque l'instruction IL ldstr est appelée, elle vérifie le dictionnaire interne et évite l'allocation de mémoire si la chaîne est déjà affectée. Remarque: String.Concat ne vérifie pas les chaînes internées.
Cette propriété de l'infrastructure .net signifie que si vous commencez à déblayer directement avec des chaînes, vous pouvez corrompre votre table interne et à son tour corrompre d'autres références à la même chaîne.
Par exemple:
// these strings get interned
string hello = "hello";
string hello2 = "hello";
string helloworld, helloworld2;
helloworld = hello;
helloworld += " world";
helloworld2 = hello;
helloworld2 += " world";
unsafe
{
// very bad, this changes an interned string which affects
// all app domains.
fixed (char* str = hello2)
{
*str = 'X';
}
fixed (char* str = helloworld2)
{
*str = 'X';
}
}
Console.WriteLine("hello = {0} , hello2 = {1}", hello, hello2);
// output: hello = Xello , hello2 = Xello
Console.WriteLine("helloworld = {0} , helloworld2 = {1}", helloworld, helloworld2);
// output : helloworld = hello world , helloworld2 = Xello world
Je pensais que la méthode 'Substring' renvoyait toujours une nouvelle chaîne, du moins c'est ce que dit le doc msdn dans la section des remarques. Voir: [String.Substring, méthode (Int32, Int32)] (https://msdn.microsoft.com/en-us/library/aka44szs%28v=vs.110%29.aspx) – neodymium