在集合中执行不受文化影响的字符串操作

System.Collections命名空间中,有一些类和成员默认提供文化敏感行为。 CaseInsensitiveComparerCaseInsensitiveHashCodeProvider 类的无参数构造函数使用 Thread.CurrentCulture 属性初始化新实例。 默认情况下,所有CollectionsUtil.CreateCaseInsensitiveHashtable方法的重载都使用Hashtable属性创建Thread.CurrentCulture类的新实例。 默认情况下,ArrayList.Sort 方法重载使用 Thread.CurrentCulture 执行区域性敏感型排序。 在字符串被用作键时,SortedList 中的排序和查找可能会受到 Thread.CurrentCulture 的影响。 请遵循本节中提供的使用建议,从命名空间的 Collections 类和方法中获取不受文化影响的结果。

注释

向比较方法传递 CultureInfo.InvariantCulture 确实会执行非区域性敏感型比较。 但是,它不会导致非语言比较,例如文件路径、注册表项和环境变量。 它也不支持基于比较结果的安全决策。 对于非语言因素的比较或基于结果的安全决策支持,应用程序应选择一种能够接收StringComparison值的比较方法。 然后,应用应传递 StringComparison

使用 CaseInsensitiveComparer 类 和 CaseInsensitiveHashCodeProvider

CaseInsensitiveHashCodeProviderCaseInsensitiveComparer 的无参数构造函数使用 Thread.CurrentCulture 来初始化类的新实例,产生区域性敏感行为。 下面的代码示例演示了 Hashtable 的构造函数,该构造函数由于使用了 CaseInsensitiveHashCodeProviderCaseInsensitiveComparer 的无参数构造函数而具有文化敏感性。

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

若要使用 HashtableCaseInsensitiveComparer 类创建非区域性敏感型 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 参数的构造函数来创建 comparercomparer 参数指定用于比较键的 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 类主题中提供了自定义固定比较器类的示例。

另请参阅