Поделиться через


Выполнение строковых операций, нечувствительных к культуре, в коллекциях

По умолчанию в пространстве имен System.Collections существуют классы и члены, обеспечивающие поведение с учетом культурных особенностей. Конструкторы без параметров для классов CaseInsensitiveComparer и CaseInsensitiveHashCodeProvider инициируют новый экземпляр, используя свойство Thread.CurrentCulture. Все перегрузки CollectionsUtil.CreateCaseInsensitiveHashtable метода создают новый экземпляр Hashtable класса с помощью Thread.CurrentCulture свойства по умолчанию. Перегрузки метода ArrayList.Sort по умолчанию используют Thread.CurrentCulture для выполнения сортировки с учетом языка и региональных параметров. Сортировка и поиск в SortedList могут быть затронуты Thread.CurrentCulture, когда строки используются в качестве ключей. Следуйте рекомендациям по использованию, приведенным в этом разделе, чтобы получить независимые от культуры результаты из этих классов и методов в Collections пространстве имен.

Замечание

Передача CultureInfo.InvariantCulture в метод сравнения выполняет сравнение без учета языка и региональных параметров. Однако это не приводит к нелингвистическому сравнению, например для путей к файлам, разделов реестра и переменных среды. Также не поддерживает принятие решений в области безопасности на основе результатов сравнения. Для нелингвистического сравнения или поддержки решений безопасности на основе результатов приложение должно использовать метод сравнения, принимаюющий StringComparison значение. Затем приложение должно передать StringComparison.

Используйте классы CaseInsensitiveComparer и CaseInsensitiveHashCodeProvider

Конструкторы без параметров для CaseInsensitiveHashCodeProvider, CaseInsensitiveComparer инициализируют новый экземпляр класса с помощью Thread.CurrentCulture, что приводит к поведению с учетом языка и региональных параметров. В следующем примере кода демонстрируется конструктор для Hashtable, чувствительный к культуре, поскольку он использует конструкторы без аргументов для CaseInsensitiveHashCodeProvider и CaseInsensitiveComparer.

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

Если вы хотите создать нечувствительную Hashtable с помощью классов CaseInsensitiveComparer и CaseInsensitiveHashCodeProvider, инициализируйте новые экземпляры этих классов с помощью конструкторов, принимающих параметр culture. culture Для параметра укажите CultureInfo.InvariantCulture. В следующем примере кода демонстрируется конструктор для нечувствительного к культурным настройкам Hashtable.

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

Используйте метод CollectionsUtil.CreateCaseInsensitiveHashTable

Этот метод CollectionsUtil.CreateCaseInsensitiveHashTable является полезным способом для создания нового экземпляра класса Hashtable, который не учитывает регистр строк. Однако все перегрузки CollectionsUtil.CreateCaseInsensitiveHashTable метода чувствительны к языковым и региональным параметрам, так как они используют Thread.CurrentCulture свойство. Невозможно создать культурально нечувствительный Hashtable с помощью этого метода. Чтобы создать нечувствительный к культуре Hashtable, используйте конструктор Hashtable, который принимает параметр culture. culture Для параметра укажите CultureInfo.InvariantCulture. В следующем примере кода демонстрируется конструктор для нечувствительного к культурным настройкам Hashtable.

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

Использование класса SortedList

A SortedList представляет коллекцию пар "ключ и значение", которые отсортированы по ключам и доступны по ключу и по индексу. Если вы используете SortedList , где строки являются ключами, сортировка и поиск могут быть затронуты свойством Thread.CurrentCulture. Чтобы получить нечувствительное к языку и региональным параметрам поведение SortedList, создайте SortedList с помощью одного из конструкторов, принимающим comparer в качестве параметра. Параметр comparer задает реализацию IComparer, которая используется при сравнении ключей. Для параметра укажите пользовательский класс сравнения, который использует CultureInfo.InvariantCulture для сравнения ключей. В следующем примере показан пользовательский класс сравнения, культурально-независимый, который можно указать в качестве comparer параметра конструктора 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);
    }
}

Как правило, если вы используете SortedList для строк без указания настраиваемого инвариантного сравнителя, изменение на Thread.CurrentCulture после заполнения списка может сделать список недействительным.

Используйте метод ArrayList.Sort

Перегрузки метода ArrayList.Sort по умолчанию выполняют чувствительную к языку и региональным параметрам сортировку, используя свойство Thread.CurrentCulture. Результаты могут различаться в зависимости от культурных особенностей из-за различных порядков сортировки. Чтобы устранить культурно-зависимое поведение, используйте перегрузки этого метода, принимающие реализацию IComparer. comparer Для параметра укажите пользовательский инвариантный класс сравнения, который используетCultureInfo.InvariantCulture. Пример пользовательского инвариантного класса сравнения представлен в разделе "Использование класса SortedList ".

См. также