String.Intern(String) Método

Definición

Recupera la referencia del sistema al 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

Cadena que se va a buscar en el grupo de internamiento.

Devoluciones

La referencia del sistema a str, si está internada; de lo contrario, una nueva referencia a una cadena con el valor de str.

Excepciones

str es null.

Ejemplos

En el ejemplo siguiente se crean dos cadenas con valores iguales y se muestra que la internación produce la misma referencia.

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

Comentarios

! [NOTA] > Aunque String.Intern garantiza que dos cadenas con valores iguales devuelvan la misma referencia internada, no garantiza que la referencia devuelta sea la misma que un literal de cadena.

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

El tiempo de ejecución puede usar el grupo de internados para conservar el almacenamiento de cadenas. Sin embargo, no se garantiza el internamiento automático de literales de cadena, en función de cómo se compiló y ejecutó el ensamblado, es posible que algunos literales no se agreguen al grupo.

En el ejemplo siguiente, la cadena s1 tiene un valor de "MyTest". La System.Text.StringBuilder clase genera un nuevo objeto de cadena que tiene el mismo valor s1que . Una referencia a esa cadena se asigna a s2. El Intern método busca una cadena que tenga el mismo valor que s2. Si s1 ya se había internado (por ejemplo, porque el ensamblado requiere la inclusión de literales de cadena), el método devuelve la misma referencia que s1, la cual se asigna a s3, y s1 y s3 son iguales al compararlos. De lo contrario, se crea una nueva entrada interna para s2 y se asigna a s3, y s1 y s3 se comparan como desiguales. En cualquier caso, s1 y s2 no se comparan iguales ya que hacen referencia 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.

Consideraciones sobre el rendimiento

Si intenta reducir la cantidad total de memoria que asigna la aplicación, tenga en cuenta que la internación de una cadena tiene dos efectos secundarios no deseados. En primer lugar, es poco probable que la memoria asignada para los objetos internados String sea liberada hasta que se termine el Common Language Runtime (CLR). El motivo es que la referencia de CLR al objeto interno String puede persistir después de que la aplicación, o incluso el dominio de la aplicación, finalice. En segundo lugar, para internar una cadena, primero debe crear la cadena. La memoria usada por el objeto String todavía debe asignarse, aunque la memoria finalmente será recogida por el recolector de basura.

El miembro de enumeración CompilationRelaxations.NoStringInterning marca un ensamblado como que no requiere la intercalación de literales de cadena. De forma predeterminada, el compilador de C# emite un CompilationRelaxationsAttribute con la marca en cada ensamblado para mejorar el NoStringInterning rendimiento, lo que significa que no se garantiza que se agreguen literales de cadena al grupo de internados. Puede personalizar NoStringInterning en un ensamblado mediante el CompilationRelaxationsAttribute atributo .

Al publicar una aplicación con AOT nativo, no se admite la desactivación NoStringInterning . Con AOT nativo, no se garantiza que los literales de cadena se agreguen al grupo de internados, por lo que Intern es posible que no encuentre ninguna coincidencia para una cadena que parezca ser un literal en el código fuente.

Se aplica a

Consulte también