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 para procurar no grupo de estagiários.

Devoluções

A referência do sistema a str, se estiver internado; caso contrário, uma nova referência a uma cadeia com o valor de str.

Exceções

str é null.

Exemplos

O exemplo seguinte cria duas cadeias com valores iguais e demonstra que interná-las produz 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
'

Observações

! [NOTA] > Embora String.Intern garanta que duas cadeias com valores iguais retornam a mesma referência internada, isso não garante que a referência retornada seja igual à de um literal de cadeia.

        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 internos pode ser usado pelo runtime para poupar armazenamento em cadeia. No entanto, a internação automática dos literais da string não é garantida—dependendo de como a assembly foi compilada e executada, alguns literais podem não ser adicionados ao pool.

No exemplo seguinte, a cadeia s1 tem o valor "MyTest". A System.Text.StringBuilder classe gera um novo objeto string que tem o mesmo valor que s1. Uma referência a essa cadeia de caracteres é atribuída a s2. O Intern método procura uma cadeia de caracteres que tenha o mesmo valor que s2. Se s1 já tivesse sido internado em memória (por exemplo, porque a montagem requer internamento literal de string), o método retorna a mesma referência de s1, que é depois atribuída a s3, e s1 e s3 são comparados como iguais. Caso contrário, uma nova entrada internada é criada para s2 e atribuída a s3, e s1 e s3 não são iguais. Em qualquer dos casos, s1 e s2 são desiguais 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 que seu aplicativo aloca, lembre-se de que a introdução de uma cadeia de caracteres tem dois efeitos colaterais indesejados. Primeiro, a memória alocada para objetos internados String provavelmente não será liberada até que o Common Language Runtime (CLR) seja encerrado. O motivo é que a referência do CLR ao objeto interned String pode persistir depois que seu aplicativo, ou até mesmo seu domínio de aplicativo, for encerrado. Em segundo lugar, para inserir uma cadeia de caracteres, deve primeiro criar a cadeia de caracteres. A memória usada pelo objeto String ainda deve ser alocada, mesmo que a memória eventualmente seja gerida pelo coletor de lixo.

O CompilationRelaxations.NoStringInterning membro de enumeração marca um assembly como não exigindo internação de literais de strings. Por defeito, o compilador C# emite a CompilationRelaxationsAttribute com a NoStringInterning flag em cada assembly para melhor desempenho, o que significa que os literais de string não têm a garantia de serem adicionados ao intern pool. Podes personalizar NoStringInterning numa montagem usando o CompilationRelaxationsAttribute atributo.

Quando publicas uma aplicação usando AOT nativo, desligar NoStringInterning não é suportado. Com AOT nativo, os literais de string não são garantidos para serem adicionados ao pool de internos, por isso Intern pode não encontrar correspondência para uma string que pareça ser literal no código-fonte.

Aplica-se a

Ver também