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


Выполнение в коллекциях строковых операций, не зависящих от языка и региональных параметров

Обновлен: Ноябрь 2007

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

Использование классов 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

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

Imports System
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 m_compareInfo;
    internal static readonly InvariantComparer Default = new
        InvariantComparer();

    internal InvariantComparer() 
    {
        m_compareInfo = CultureInfo.InvariantCulture.CompareInfo;
    }
    
    public int Compare(Object a, Object b)
    {
        String sa = a as String;
        String sb = b as String;
        if (sa != null && sb != null)
            return m_compareInfo.Compare(sa, sb);
        else
            return Comparer.Default.Compare(a,b);
    }
}

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

Использование метода ArrayList.Sort

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

См. также

Ссылки

CaseInsensitiveComparer

CaseInsensitiveHashCodeProvider

Метод CollectionsUtil.CreateCaseInsensitiveHashTable

ArrayList.Sort

SortedList

Hashtable

IComparer

Другие ресурсы

Выполнение строковых операций, не зависящих от языка и региональных параметров