String.Intern(String) Méthode

Définition

Récupère la référence du système au fichier spécifié String.

public:
 static System::String ^ Intern(System::String ^ str);
public static string Intern(string str);
static member Intern : string -> string
Public Shared Function Intern (str As String) As String

Paramètres

str
String

Chaîne à rechercher dans le pool de stagiaires.

Retours

Référence du système à str, si elle est interne ; sinon, une nouvelle référence à une chaîne avec la valeur de str.

Exceptions

str a la valeur null.

Exemples

L’exemple suivant crée deux chaînes avec des valeurs égales et montre que leur interne génère la même référence.

// Sample for String.Intern(String)
using System;
using System.Text;

class Sample
{
    public static void Main()
    {
        string s1 = new StringBuilder().Append("My").Append("Test").ToString();
        string s2 = new StringBuilder().Append("My").Append("Test").ToString();
        Console.WriteLine($"s1 == {s1}");
        Console.WriteLine($"s2 == {s2}");
        Console.WriteLine($"Are s1 and s2 equal in value? {s1 == s2}");
        Console.WriteLine($"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}");

        string i1 = String.Intern(s1);
        string i2 = String.Intern(s2);
        Console.WriteLine($"After interning:");
        Console.WriteLine($"  Are i1 and i2 equal in value? {i1 == i2}");
        Console.WriteLine($"  Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}");
    }
}
/*
This example produces the following results:
s1 == MyTest
s2 == MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
  Are i1 and i2 equal in value? True
  Are i1 and i2 the same reference? True
*/
// Sample for String.Intern(String)
open System
open System.Text

let s1 = StringBuilder().Append("My").Append("Test").ToString()
let s2 = StringBuilder().Append("My").Append("Test").ToString()
printfn $"s1 = {s1}"
printfn $"s2 = {s2}"
printfn $"Are s1 and s2 equal in value? {s1 = s2}"
printfn $"Are s1 and s2 the same reference? {Object.ReferenceEquals(s1, s2)}"

let i1 = String.Intern s1
let i2 = String.Intern s2
printfn "After interning:"
printfn $"  Are i1 and i2 equal in value? {i1 = i2}"
printfn $"  Are i1 and i2 the same reference? {Object.ReferenceEquals(i1, i2)}"
(*
This example produces the following results:
s1 = MyTest
s2 = MyTest
Are s1 and s2 equal in value? True
Are s1 and s2 the same reference? False
After interning:
  Are i1 and i2 equal in value? True
  Are i1 and i2 the same reference? True
*)
Imports System.Text

Class Sample

    Public Shared Sub Run()
        Dim s1 As String = New StringBuilder().Append("My").Append("Test").ToString()
        Dim s2 As String = New StringBuilder().Append("My").Append("Test").ToString()
        Console.WriteLine($"s1 = {s1}")
        Console.WriteLine($"s2 = {s2}")
        Console.WriteLine($"Are s1 and s2 equal in value? {s1 = s2}")
        Console.WriteLine($"Are s1 and s2 the same reference? {s1 Is s2}")

        Dim i1 As String = String.Intern(s1)
        Dim i2 As String = String.Intern(s2)
        Console.WriteLine("After interning:")
        Console.WriteLine($"  Are i1 and i2 equal in value? {i1 = i2}")
        Console.WriteLine($"  Are i1 and i2 the same reference? {i1 Is i2}")
    End Sub
End Class
'
's1 = MyTest
's2 = MyTest
'Are s1 and s2 equal in value? True
'Are s1 and s2 the same reference? False
'After interning:
'  Are i1 and i2 equal in value? True
'  Are i1 and i2 the same reference? True
'

Remarques

! [REMARQUE] > Même si String.Intern deux chaînes avec des valeurs égales retournent la même référence interne, elle ne garantit pas que la référence retournée est identique à un littéral de chaîne.

        The common language runtime maintains a table, called the *intern pool*, that holds a single reference for each unique string value. The <xref:System.String.Intern*> method uses the intern pool to search for a string equal to the value of `str`. If no such string exists, a reference to `str` is added to the pool, and that reference is returned. (In contrast, the <xref:System.String.IsInterned(System.String)> method returns a null reference if the requested string doesn't exist in the intern pool.)

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.

S’applique à

Voir aussi