Metodo System.String.Intern
Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.
Common Language Runtime conserva l'archiviazione di stringhe mantenendo una tabella, denominata pool di stagisti, che contiene un singolo riferimento a ogni stringa letterale univoca dichiarata o creata a livello di codice nel programma. Di conseguenza, un'istanza di una stringa letterale con un determinato valore esiste una sola volta nel sistema.
Ad esempio, se si assegna la stessa stringa letterale a diverse variabili, il runtime recupera lo stesso riferimento alla stringa letterale dal pool di stagisti e lo assegna a ogni variabile.
Il Intern metodo usa il pool di stagisti per cercare una stringa uguale al valore di str
. Se tale stringa esiste, viene restituito il relativo riferimento nel pool di stagisti. Se la stringa non esiste, viene aggiunto un riferimento al str
pool di stagisti, viene restituito tale riferimento.
Nell'esempio seguente la stringa s1, che ha un valore "MyTest", è già internata perché è un valore letterale nel programma. La System.Text.StringBuilder classe genera un nuovo oggetto stringa con lo stesso valore di s1. Un riferimento a tale stringa viene assegnato a s2. Il Intern metodo cerca una stringa con lo stesso valore di s2. Poiché tale stringa esiste, il metodo restituisce lo stesso riferimento assegnato a s1. Tale riferimento viene quindi assegnato a s3. I riferimenti s1 e s2 vengono confrontati in modo diverso perché fanno riferimento a oggetti diversi; i riferimenti s1 e s3 confrontano uguale perché fanno riferimento alla stessa stringa.
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.
Confrontare questo metodo con il IsInterned metodo .
Nell'esempio seguente alla variabile str1
viene assegnato un riferimento a String.Emptye alla variabile str2
viene assegnato il riferimento String.Empty restituito chiamando il Intern metodo dopo la conversione di un StringBuilder oggetto il cui valore è String.Empty in una stringa. Vengono quindi confrontati i riferimenti contenuti in str1
e str2
per verificarne l'uguaglianza. str1
e str2
sono uguali.
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
Considerazioni sulle prestazioni
Se si sta tentando di ridurre la quantità totale di memoria allocata dall'applicazione, tenere presente che l'interno di una stringa ha due effetti collaterali indesiderati. Prima di tutto, la memoria allocata per gli oggetti interni String non viene probabilmente rilasciata fino al termine di Common Language Runtime (CLR). Il motivo è che il riferimento clr all'oggetto interno String può persistere dopo che l'applicazione, o anche il dominio dell'applicazione, termina. In secondo luogo, per internare una stringa, è prima necessario creare la stringa. La memoria usata dall'oggetto String deve comunque essere allocata, anche se alla fine la memoria verrà sottoposto a Garbage Collection.
Il CompilationRelaxations.NoStringInterning membro di enumerazione contrassegna un assembly perché non richiede l'interno dei valori letterali stringa. È possibile applicare NoStringInterning a un assembly usando l'attributo CompilationRelaxationsAttribute . Inoltre, quando si usa Ngen.exe (Generatore di immagini native) per compilare un assembly in anticipo in fase di esecuzione, le stringhe non vengono interne tra i moduli.