Condividi tramite


Metodo System.String.Intern

Annotazioni

Questo articolo fornisce osservazioni supplementari alla documentazione di riferimento per questa API.

Common Language Runtime mantiene una tabella, denominata pool di internamento, che contiene un singolo riferimento per ogni valore stringa univoco. Il Intern metodo usa il pool di stagisti per cercare una stringa uguale al valore di str. Se tale stringa non esiste, viene aggiunto un riferimento str al pool e viene restituito tale riferimento. Al contrario, il IsInterned(String) metodo restituisce un riferimento Null se la stringa richiesta non esiste nel pool di stagisti.

Il pool di stagisti può essere usato dal runtime per risparmiare spazio di archiviazione delle stringhe. Tuttavia, l'internamento automatico dei letterali di stringa non è garantito; a seconda di come l'assembly è stato compilato ed eseguito, alcuni letterali potrebbero non essere aggiunti al pool.

Nell'esempio seguente la stringa s1 ha il valore "MyTest". 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. Se s1 è già stato internato (ad esempio, perché l'assembly richiede l'interning di stringhe letterali), il metodo restituisce lo stesso riferimento di s1, che viene quindi assegnato a s3, e s1 e s3 vengono confrontati come uguali. In caso contrario, viene creata una nuova voce internata per s2 e assegnata a s3, mentre s1 e s3 vengono confrontati come distinti. In entrambi i casi, s1 e s2 risultano diversi perché fanno riferimento a oggetti diversi.

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.

Considerazioni sulle prestazioni

Se si sta cercando di ridurre la quantità totale di memoria allocata dall'applicazione, tieni presente che internare 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à gestita dal Garbage Collector.

Il CompilationRelaxations.NoStringInterning membro di enumerazione contrassegna un assembly che non richiede l'internamento dei letterali di stringa. Per impostazione predefinita, il compilatore C# emette un CompilationRelaxationsAttribute con il NoStringInterning flag in ogni assembly per migliorare le prestazioni, ciò significa che i letterali di stringa non sono garantiti per l'aggiunta al pool di internamento. È possibile personalizzare NoStringInterning in un assembly usando l'attributo CompilationRelaxationsAttribute .

Quando si pubblica un'app con AOT nativo, la disattivazione NoStringInterning non è supportata. Con AOT nativo, non è garantito che i valori letterali stringa vengano aggiunti al pool di stagisti, quindi Intern potrebbe non trovare una corrispondenza per una stringa che sembra essere un valore letterale nel codice sorgente.