String.Intern(String) Método

Definição

Recupera a referência do sistema ao especificado 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

Parâmetros

str
String

Uma cadeia de caracteres a ser pesquisada no pool de estagiários.

Retornos

A referência do sistema para str, se ele for interno; caso contrário, uma nova referência a uma cadeia de caracteres com o valor de str.

Exceções

str é null.

Exemplos

O exemplo a seguir cria duas cadeias de caracteres com valores iguais e demonstra que estagiá-las gera a mesma referência.

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

Comentários

! [OBSERVAÇÃO] > Embora String.Intern garanta que duas cadeias de caracteres com valores iguais retornem a mesma referência interna, ela não garante que a referência retornada seja a mesma que um literal de cadeia de caracteres.

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

O pool de estagiários pode ser usado pelo runtime para conservar o armazenamento de cadeias de caracteres. No entanto, a inserção automática de literais de strings não é garantida—dependendo de como o assembly foi compilado e executado, alguns literais podem não ser adicionados ao pool.

No exemplo a seguir, a cadeia de caracteres s1 tem um valor de "MyTest". A System.Text.StringBuilder classe gera um novo objeto de cadeia de caracteres que tem o mesmo valor que s1. Uma referência a essa cadeia de caracteres é atribuída a s2. O Intern método pesquisa uma cadeia de caracteres que tem o mesmo valor que s2. Se s1 já estiver internado (por exemplo, porque a montagem requer a internação literal de cadeias de caracteres), o método retornará a mesma referência s1 que, em seguida, é atribuída a s3, e s1 e s3 se comparam como iguais. Caso contrário, uma nova entrada internada s2 será criada e atribuída a s3, e s1 e s3 serão comparados como desiguais. Em ambos os casos, s1 e s2 se comparam de forma desigual porque se referem a objetos diferentes.

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.

Considerações sobre desempenho

Se você estiver tentando reduzir a quantidade total de memória alocada pelo aplicativo, tenha em mente que a internação de uma cadeia de caracteres terá dois efeitos colaterais indesejados. Primeiro, a memória alocada para objetos internos String provavelmente não será liberada até que o CLR (Common Language Runtime) seja encerrado. O motivo é que a referência do CLR ao objeto interno String pode persistir após o término do aplicativo ou até mesmo do domínio do aplicativo. Em segundo lugar, para internar uma cadeia de caracteres, primeiro você deve criá-la. A memória usada pelo objeto String ainda deve ser alocada, mesmo que a memória eventualmente seja coletada pelo coletor de lixo.

O membro de enumeração CompilationRelaxations.NoStringInterning marca um assembly como não exigindo internação literal de cadeia de caracteres. Por padrão, o compilador C# emite um CompilationRelaxationsAttribute com o NoStringInterning sinalizador em cada assembly para melhor desempenho, o que significa que literais de cadeia de caracteres não têm garantia de serem adicionados ao pool de estagiários. Você pode personalizar NoStringInterning em um assembly usando o atributo CompilationRelaxationsAttribute.

Quando você publica um aplicativo usando a AOT nativa, não há suporte para desativar NoStringInterning . Com a AOT nativa, não há garantia de que literais de cadeia de caracteres sejam adicionados ao pool de estagiários, portanto Intern , talvez não encontre uma correspondência para uma cadeia de caracteres que parece ser um literal no código-fonte.

Aplica-se a

Confira também