Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.
Common Language Runtime mantiene una tabla, denominada grupo de internados, que contiene una única referencia para cada valor de cadena único. El Intern método usa el grupo de internamiento para buscar una cadena igual al valor de str. Si no existe ninguna cadena de este tipo, se agrega una referencia a str en el pool, y esa referencia se devuelve. (Por el contrario, el método IsInterned(String) devuelve una referencia nula si la cadena solicitada no existe en el grupo de internamiento).
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.