Realización de operaciones de cadenas que no tienen en cuenta las referencias culturales en colecciones

En el espacio de nombres System.Collections hay clases y miembros que proporcionan, de manera predeterminada, el comportamiento que tiene en cuenta la referencia cultural. Los constructores sin parámetros de las clases CaseInsensitiveComparer y CaseInsensitiveHashCodeProvider inicializan una instancia nueva con la propiedad Thread.CurrentCulture. Todas las sobrecargas del método CollectionsUtil.CreateCaseInsensitiveHashtable crean una instancia de la clase Hashtable mediante la propiedad Thread.CurrentCulture de forma predeterminada. Las sobrecargas del método ArrayList.Sort realizan ordenaciones que tienen en cuenta las referencias culturales de manera predeterminada con Thread.CurrentCulture. SortedList puede afectar la ordenación y la búsqueda en Thread.CurrentCulture cuando las cadenas se usan como las claves. Siga las recomendaciones de uso que se proporcionan en esta sección para obtener resultados que no tienen en cuenta la referencia cultural de estas clases y métodos en el espacio de nombres Collections.

Nota

Pasar CultureInfo.InvariantCulture a un método de comparación realiza una comparación que no tiene en cuenta la referencia cultural. Si embargo, no provoca una comparación no lingüística, por ejemplo, para las rutas de acceso de archivo, las claves del Registro y las variables de entorno. Tampoco admite las decisiones de seguridad basadas en el resultado de la comparación. Para una comparación no lingüística o la compatibilidad con las decisiones de seguridad basadas en los resultados, la aplicación debe usar un método de comparación que acepte un valor StringComparison. A continuación, la aplicación debe pasar StringComparison.

Uso de las clases CaseInsensitiveComparer y CaseInsensitiveHashCodeProvider

Los constructores sin parámetros para CaseInsensitiveHashCodeProvider y CaseInsensitiveComparer inicializan una instancia nueva de la clase con Thread.CurrentCulture, lo que genera un comportamiento que tiene en cuenta las referencias culturales. En el ejemplo de código siguiente se muestra el constructor de Hashtable que tiene en cuenta las referencias culturales porque usa los constructores sin parámetros para CaseInsensitiveHashCodeProvider y CaseInsensitiveComparer.

internalHashtable = New Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default)
internalHashtable = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);

Si desea crear Hashtable que no tiene en cuenta las referencias culturales con las clases CaseInsensitiveComparer y CaseInsensitiveHashCodeProvider, inicialice instancias nuevas de estas clases con los constructores que aceptan un parámetro culture. Para el parámetro culture, especifique CultureInfo.InvariantCulture. El ejemplo de código siguiente muestra el constructor para un Hashtable que no tiene en cuenta las referencias culturales.

internalHashtable = New Hashtable(New
    CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture),
    New CaseInsensitiveComparer(CultureInfo.InvariantCulture))
internalHashtable = new Hashtable(new CaseInsensitiveHashCodeProvider
    (CultureInfo.InvariantCulture),
    new CaseInsensitiveComparer(CultureInfo.InvariantCulture));

Uso del método CollectionsUtil.CreateCaseInsensitiveHashTable

El método CollectionsUtil.CreateCaseInsensitiveHashTable es un acceso directo para crear una instancia de la clase Hashtable que no toma en cuenta las mayúsculas y minúsculas de las cadenas. Sin embargo, todas las sobrecargas del método CollectionsUtil.CreateCaseInsensitiveHashTable tienen en cuenta las referencias culturales porque usan la propiedad Thread.CurrentCulture. No puede crear un Hashtable que no tiene en cuenta las referencias culturales con este método. Para crear un Hashtable que no tiene en cuenta las referencias culturales, use el constructor Hashtable que acepta un parámetro culture. Para el parámetro culture, especifique CultureInfo.InvariantCulture. El ejemplo de código siguiente muestra el constructor para un Hashtable que no tiene en cuenta las referencias culturales.

internalHashtable = New Hashtable(New
    CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture),
    New CaseInsensitiveComparer(CultureInfo.InvariantCulture))
internalHashtable = new Hashtable(new CaseInsensitiveHashCodeProvider
    (CultureInfo.InvariantCulture),
    new CaseInsensitiveComparer(CultureInfo.InvariantCulture));

Use la clase SortedList.

SortedList representa una colección de pares clave-valor ordenados por claves a los que se accede por clave y por índice. Cuando usa SortedList donde las cadenas son las claves, la propiedad Thread.CurrentCulture puede afectar la ordenación y la búsqueda. Para obtener el comportamiento que no tiene en cuenta las referencias culturales desde SortedList, cree SortedList con uno de los constructores que acepta un parámetro comparer. El parámetro comparer especifica la implementación IComparer para usarla al comparar claves. Para el parámetro, especifique una clase de comparador personalizada que usaCultureInfo.InvariantCulture para comparar claves. En el ejemplo siguiente se muestra una clase de comparación que no tiene en cuenta las referencias culturales y que puede especificar como el parámetro comparer para un constructor SortedList.

Imports System.Collections
Imports System.Globalization

Friend Class InvariantComparer
    Implements IComparer
    Private m_compareInfo As CompareInfo
    Friend Shared [Default] As New InvariantComparer()

    Friend Sub New()
        m_compareInfo = CultureInfo.InvariantCulture.CompareInfo
    End Sub

    Public Function Compare(a As Object, b As Object) As Integer _
            Implements IComparer.Compare
        Dim sa As String = CType(a, String)
        Dim sb As String = CType(b, String)
        If Not (sa Is Nothing) And Not (sb Is Nothing) Then
            Return m_compareInfo.Compare(sa, sb)
        Else
            Return Comparer.Default.Compare(a, b)
        End If
    End Function
End Class
using System;
using System.Collections;
using System.Globalization;

internal class InvariantComparer : IComparer
{
    private CompareInfo _compareInfo;
    internal static readonly InvariantComparer Default = new
        InvariantComparer();

    internal InvariantComparer()
    {
        _compareInfo = CultureInfo.InvariantCulture.CompareInfo;
    }

    public int Compare(Object a, Object b)
    {
        if (a is string sa && b is string sb)
            return _compareInfo.Compare(sa, sb);
        else
            return Comparer.Default.Compare(a,b);
    }
}

En general, si usa SortedList en las cadenas sin especificar un comparador invariable personalizado, un cambio en Thread.CurrentCulture una vez que se rellena la lista puede invalidarla.

Uso del método ArrayList.Sort

Las sobrecargas del método ArrayList.Sort realizan ordenaciones que tienen en cuenta las referencias culturales de manera predeterminada con la propiedad Thread.CurrentCulture. Los resultados pueden variar según la referencia cultural debido a criterios de ordenación distintos. Para eliminar el comportamiento que tiene en cuenta las referencias culturales, use las sobrecargas de este método que aceptan una implementación IComparer. Para el parámetro comparer, especifique una clase de comparador invariable personalizada que use CultureInfo.InvariantCulture. En el tema Uso de la clase SortedList se proporciona un ejemplo de una clase de comparador invariable personalizada.

Vea también