Выполнение в коллекциях строковых операций, не зависящих от языка и региональных параметров
Обновлен: Ноябрь 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.
См. также
Ссылки
CaseInsensitiveHashCodeProvider
Метод CollectionsUtil.CreateCaseInsensitiveHashTable
Другие ресурсы
Выполнение строковых операций, не зависящих от языка и региональных параметров