Méthode System.String.Intern
Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.
Le Common Language Runtime conserve le stockage de chaînes en conservant une table, appelée pool interne, qui contient une référence unique à chaque chaîne littérale unique déclarée ou créée par programme dans votre programme. Par conséquent, une instance d’une chaîne littérale avec une valeur particulière existe une seule fois dans le système.
Par exemple, si vous affectez la même chaîne littérale à plusieurs variables, le runtime récupère la même référence à la chaîne littérale du pool interne et l’affecte à chaque variable.
La Intern méthode utilise le pool interne pour rechercher une chaîne égale à la valeur de str
. Si une telle chaîne existe, sa référence dans le pool interne est retournée. Si la chaîne n’existe pas, une référence à laquelle est str
ajoutée au pool interne, cette référence est retournée.
Dans l’exemple suivant, la chaîne s1, qui a la valeur « MyTest », est déjà interne, car elle est un littéral dans le programme. La System.Text.StringBuilder classe génère un nouvel objet de chaîne qui a la même valeur que s1. Une référence à cette chaîne est affectée à s2. La Intern méthode recherche une chaîne qui a la même valeur que s2. Étant donné qu’une telle chaîne existe, la méthode retourne la même référence que celle affectée à s1. Cette référence est ensuite affectée à s3. Les références s1 et s2 comparent inégalement, car elles font référence à différents objets ; références s1 et s3 comparent égales, car elles font référence à la même chaîne.
string s1 = "MyTest";
string s2 = new StringBuilder().Append("My").Append("Test").ToString();
string s3 = String.Intern(s2);
Console.WriteLine((Object)s2==(Object)s1); // Different references.
Console.WriteLine((Object)s3==(Object)s1); // The same reference.
let s1 = "MyTest"
let s2 = StringBuilder().Append("My").Append("Test").ToString()
let s3 = String.Intern s2
printfn $"{s2 :> obj = s1 :> obj}" // Different references.
printfn $"{s3 :> obj = s1 :> obj}" // The same reference.
Dim s1 As String = "MyTest"
Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString()
Dim s3 As String = String.Intern(s2)
Console.WriteLine(CObj(s2) Is CObj(s1)) ' Different references.
Console.WriteLine(CObj(s3) Is CObj(s1)) ' The same reference.
Comparez cette méthode à la IsInterned méthode.
Dans l’exemple suivant, la variable str1
est affectée à String.Emptyune référence et la variable str2
est affectée à celle-ci String.Empty en appelant la Intern méthode après la conversion d’un StringBuilder objet dont la valeur est String.Empty en chaîne. Ensuite, les références contenues dans str1
et str2
sont comparées pour l’égalité. str1
et str2
sont égaux.
string str1 = String.Empty;
string str2 = String.Empty;
StringBuilder sb = new StringBuilder().Append(String.Empty);
str2 = String.Intern(sb.ToString());
if ((object)str1 == (object)str2)
Console.WriteLine("The strings are equal.");
else
Console.WriteLine("The strings are not equal.");
let str1 = String.Empty
let str2 = String.Empty
let sb = StringBuilder().Append String.Empty
let str3 = String.Intern(string sb)
if (str1 :> obj) = (str3 :> obj) then
printfn "The strings are equal."
else
printfn "The strings are not equal."
Dim str1 As String = String.Empty
Dim str2 As String = String.Empty
Dim sb As StringBuilder = New StringBuilder().Append(String.Empty)
str2 = String.Intern(sb.ToString())
If CObj(str1) Is CObj(str2) Then
Console.WriteLine("The strings are equal.")
Else
Console.WriteLine("The strings are not equal.")
End If
Considérations relatives aux performances
Si vous essayez de réduire la quantité totale de mémoire allouée par votre application, gardez à l’esprit que l’internement d’une chaîne a deux effets secondaires indésirables. Tout d’abord, la mémoire allouée pour les objets internes String n’est probablement pas libérée tant que le Common Language Runtime (CLR) n’est pas terminé. La raison est que la référence du CLR à l’objet interne String peut persister après l’arrêt de votre application, voire de votre domaine d’application. Deuxièmement, pour interner une chaîne, vous devez d’abord créer la chaîne. La mémoire utilisée par l’objet String doit toujours être allouée, même si la mémoire sera finalement récupérée par le garbage collection.
Le CompilationRelaxations.NoStringInterning membre d’énumération marque un assembly comme ne nécessitant pas de internement littéral de chaîne. Vous pouvez appliquer NoStringInterning à un assembly à l’aide de l’attribut CompilationRelaxationsAttribute . En outre, lorsque vous utilisez Ngen.exe (Générateur d’images natives) pour compiler un assembly à l’avance de l’exécution, les chaînes ne sont pas internes entre les modules.