String.Intern(String) Método
Definição
Importante
Algumas informações se referem a produtos de pré-lançamento que podem ser substancialmente modificados antes do lançamento. A Microsoft não oferece garantias, expressas ou implícitas, das informações aqui fornecidas.
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.Interngaranta 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.