String.Intern(String) Metodo

Definizione

Recupera il riferimento del sistema all'oggetto specificato 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

Parametri

str
String

Stringa da cercare nel pool di stagisti.

Valori restituiti

Riferimento del sistema a str, se internato; in caso contrario, un nuovo riferimento a una stringa con il valore di str.

Eccezioni

str è null.

Esempio

Nell'esempio seguente vengono create due stringhe con valori uguali e viene dimostrato che l'interno di tali stringhe restituisce lo stesso riferimento.

// 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
'

Commenti

! [NOTA] > Anche se String.Intern garantisce che due stringhe con valori uguali restituiscono lo stesso riferimento interno, non garantisce che il riferimento restituito sia uguale a un valore letterale stringa.

        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.)

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.

Si applica a

Vedi anche