Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Cet article fournit des remarques supplémentaires à la documentation de référence de cette API.
Le Common Language Runtime gère une table, appelée pool interne, qui contient une référence unique pour chaque valeur de chaîne unique. La Intern méthode utilise le pool interne pour rechercher une chaîne égale à la valeur de str. Si aucune chaîne de ce type n'existe, une référence à str est ajoutée au pool, et cette référence est retournée. (En revanche, la IsInterned(String) méthode retourne une référence Null si la chaîne demandée n’existe pas dans le pool interne.)
Le pool interne peut être utilisé par le runtime pour conserver le stockage de chaînes. Toutefois, l'internement automatique des chaînes littérales n’est pas garanti. Selon la façon dont l'assemblage a été compilé ou exécuté, certains littéraux peuvent ne pas être ajoutés au pool.
Dans l’exemple suivant, la chaîne s1 a la valeur « MyTest ». 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. Si s1 a déjà été interné (par exemple, parce que l'assemblage nécessite un internement littéral de chaîne), la méthode retourne la même référence que s1, qui est ensuite affectée à s3, et s1 et s3 sont égaux. Dans le cas contraire, une nouvelle entrée internée est créée pour s2 et affectée à s3, et s1 et s3 sont comparés et trouvés inégaux. Dans les deux cas, s1 et s2 ne sont pas égaux, car ils font référence à des objets différents.
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.
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 mettre une chaîne en mémoire interne, 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 elle sera finalement récupérée par le récupérateur de mémoire.
Le membre d'énumération CompilationRelaxations.NoStringInterning marque un assembly comme ne nécessitant pas la centralisation de littéraux de chaîne. Par défaut, le compilateur C# émet un CompilationRelaxationsAttribute avec le drapeau NoStringInterning sur chaque assembly pour de meilleures performances, ce qui signifie que les littéraux de chaîne ne sont pas garantis d'être ajoutés au pool d'internement. Vous pouvez personnaliser NoStringInterning sur un assembly à l’aide de l’attribut CompilationRelaxationsAttribute .
Lorsque vous publiez une application à l’aide d’AOT natif, la désactivation NoStringInterning n’est pas prise en charge. Avec AOT natif, les littéraux de chaîne ne sont pas garantis d'être ajoutés au pool d'internement, il est donc possible que Intern ne trouve pas de correspondance pour une chaîne qui semble être un littéral dans le code source.