Método System.String.Intern

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

Common Language Runtime conserva el almacenamiento de cadenas manteniendo una tabla, denominada grupo de internados, que contiene una sola referencia a cada cadena literal única declarada o creada mediante programación en el programa. Por lo tanto, una instancia de una cadena literal con un valor determinado solo existe una vez en el sistema.

Por ejemplo, si asigna la misma cadena literal a varias variables, el tiempo de ejecución recupera la misma referencia a la cadena literal del grupo de internados y la asigna a cada variable.

El Intern método usa el grupo de internamiento para buscar una cadena igual al valor de str. Si existe dicha cadena, se devuelve su referencia en el grupo de internados. Si la cadena no existe, se agrega una referencia al str grupo de internados y se devuelve esa referencia.

En el ejemplo siguiente, la cadena s1, que tiene un valor de "MyTest", ya está internada porque es un literal del programa. La System.Text.StringBuilder clase genera un nuevo objeto de cadena que tiene el mismo valor que s1. Una referencia a esa cadena se asigna a s2. El Intern método busca una cadena que tenga el mismo valor que s2. Dado que existe una cadena de este tipo, el método devuelve la misma referencia que se asigna a s1. A continuación, esa referencia se asigna a s3. Las referencias s1 y s2 comparan desiguales porque hacen referencia a objetos diferentes; hace referencia a s1 y s3 iguales porque hacen referencia a la misma cadena.

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.

Compare este método con el IsInterned método .

En el ejemplo siguiente, a la variable str1 se le asigna una referencia a String.Emptyy a la variable str2 se le asigna la referencia a String.Empty que se devuelve llamando al Intern método después de convertir un StringBuilder objeto cuyo valor es String.Empty a una cadena. A continuación, las referencias contenidas en str1 y str2 se comparan por igualdad. str1 y str2 son iguales.

string str1 = String.Empty;
string str2 = String.Empty;

StringBuilder sb = new StringBuilder().Append(String.Empty);
str2 = String.Intern(sb.ToString());

if ((object)str1 == (object)str2)
    Console.WriteLine("The strings are equal.");
else
    Console.WriteLine("The strings are not equal.");
let str1 = String.Empty
let str2 = String.Empty

let sb = StringBuilder().Append String.Empty
let str3 = String.Intern(string sb)

if (str1 :> obj) = (str3 :> obj) then
    printfn "The strings are equal."
else
    printfn "The strings are not equal."
Dim str1 As String = String.Empty
Dim str2 As String = String.Empty

Dim sb As StringBuilder = New StringBuilder().Append(String.Empty)
str2 = String.Intern(sb.ToString())

If CObj(str1) Is CObj(str2) Then
    Console.WriteLine("The strings are equal.")
Else
    Console.WriteLine("The strings are not equal.")
End If

Consideraciones de 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 probable que la memoria asignada para los objetos internados String se libere hasta que finalice 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 String objeto todavía debe asignarse, aunque la memoria finalmente se recolecte de elementos no utilizados.

El CompilationRelaxations.NoStringInterning miembro de enumeración marca un ensamblado como no requiere el interning de literales de cadena. Puede aplicar NoStringInterning a un ensamblado mediante el CompilationRelaxationsAttribute atributo . Además, cuando se usa Ngen.exe (Generador de imágenes nativas) para compilar un ensamblado con antelación del tiempo de ejecución, las cadenas no se internan entre módulos.