| title | ms.custom | ms.date | ms.prod | ms.reviewer | ms.suite | ms.technology | ms.tgt_pltfrm | ms.topic | helpviewer_keywords | ms.assetid | caps.latest.revision | author | ms.author | manager | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Performing Culture-Insensitive String Operations in Collections |
03/30/2017 |
.net |
dotnet-standard |
article |
|
5cdc9396-a64b-4615-a1cd-b605db4c5983 |
12 |
rpetrusha |
ronpet |
wpickett |
Performing Culture-Insensitive String Operations in Collections
There are classes and members in the xref:System.Collections namespace that provide culture-sensitive behavior by default. The default constructors for the xref:System.Collections.CaseInsensitiveComparer and xref:System.Collections.CaseInsensitiveHashCodeProvider classes initialize a new instance using the xref:System.Threading.Thread.CurrentCulture%2A?displayProperty=nameWithType property. All overloads of the xref:System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable%2A?displayProperty=nameWithType method create a new instance of the xref:System.Collections.Hashtable class using the Thread.CurrentCulture property by default. Overloads of the xref:System.Collections.ArrayList.Sort%2A?displayProperty=nameWithType method perform culture-sensitive sorts by default using Thread.CurrentCulture. Sorting and lookup in a xref:System.Collections.SortedList can be affected by Thread.CurrentCulture when strings are used as the keys. Follow the usage recommendations provided in this section to obtain culture-insensitive results from these classes and methods in the Collections namespace.
Note Passing xref:System.Globalization.CultureInfo.InvariantCulture%2A?displayProperty=nameWithType to a comparison method does perform a culture-insensitive comparison. However, it does not cause a non-linguistic comparison, for example, for file paths, registry keys, and environment variables. Neither does it support security decisions based on the comparison result. For a non-linguistic comparison or support for result-based security decisions, the application should use a comparison method that accepts a xref:System.StringComparison value. The application should then pass xref:System.StringComparison.
Using the CaseInsensitiveComparer and CaseInsensitiveHashCodeProvider Classes
The default constructors for CaseInsensitiveHashCodeProvider and CaseInsensitiveComparer initialize a new instance of the class using the Thread.CurrentCulture, resulting in culture-sensitive behavior. The following code example demonstrates the constructor for a Hashtable that is culture-sensitive because it uses the default constructors for CaseInsensitiveHashCodeProvider and CaseInsensitiveComparer.
internalHashtable = New Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default) internalHashtable = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default); If you want to create a culture-insensitive Hashtable using the CaseInsensitiveComparer and CaseInsensitiveHashCodeProvider classes, initialize new instances of these classes using the constructors that accept a culture parameter. For the culture parameter, specify xref:System.Globalization.CultureInfo.InvariantCulture%2A?displayProperty=nameWithType. The following code example demonstrates the constructor for a culture-insensitive Hashtable.
internalHashtable = New Hashtable(New
CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture),
New CaseInsensitiveComparer(CultureInfo.InvariantCulture)) internalHashtable = new Hashtable(new CaseInsensitiveHashCodeProvider
(CultureInfo.InvariantCulture),
new CaseInsensitiveComparer(CultureInfo.InvariantCulture)); Using the CollectionsUtil.CreateCaseInsensitiveHashTable Method
The CollectionsUtil.CreateCaseInsensitiveHashTable method is a useful shortcut for creating a new instance of the Hashtable class that ignores the case of strings. However, all overloads of the CollectionsUtil.CreateCaseInsensitiveHashTable method are culture-sensitive because they use the Thread.CurrentCulture property. You cannot create a culture-insensitive Hashtable using this method. To create a culture-insensitive Hashtable, use the Hashtable constructor that accepts a culture parameter. For the culture parameter, specify CultureInfo.InvariantCulture. The following code example demonstrates the constructor for a culture-insensitive Hashtable.
internalHashtable = New Hashtable(New
CaseInsensitiveHashCodeProvider(CultureInfo.InvariantCulture),
New CaseInsensitiveComparer(CultureInfo.InvariantCulture)) internalHashtable = new Hashtable(new CaseInsensitiveHashCodeProvider
(CultureInfo.InvariantCulture),
new CaseInsensitiveComparer(CultureInfo.InvariantCulture)); Using the SortedList Class
A SortedList represents a collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index. When you use a SortedList where strings are the keys, the sorting and lookup can be affected by the Thread.CurrentCulture property. To obtain culture-insensitive behavior from a SortedList, create a SortedList using one of the constructors that accepts a comparer parameter. The comparer parameter specifies the xref:System.Collections.IComparer implementation to use when comparing keys. For the parameter, specify a custom comparer class that uses CultureInfo.InvariantCulture to compare keys. The following example illustrates a custom culture-insensitive comparer class that you can specify as the comparer parameter to a SortedList constructor.
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);
}
} In general, if you use a SortedList on strings without specifying a custom invariant comparer, a change to Thread.CurrentCulture after the list has been populated can invalidate the list.
Using the ArrayList.Sort Method
Overloads of the ArrayList.Sort method perform culture-sensitive sorts by default using the Thread.CurrentCulture property. Results can vary by culture due to different sort orders. To eliminate culture-sensitive behavior, use the overloads of this method that accept an IComparer implementation. For the comparer parameter, specify a custom invariant comparer class that uses CultureInfo.InvariantCulture. An example of a custom invariant comparer class is provided in the Using the SortedList Class topic.
See Also
xref:System.Collections.CaseInsensitiveComparer
xref:System.Collections.CaseInsensitiveHashCodeProvider
xref:System.Collections.ArrayList.Sort%2A?displayProperty=nameWithType
xref:System.Collections.SortedList
xref:System.Collections.Hashtable
xref:System.Collections.IComparer
Performing Culture-Insensitive String Operations
xref:System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable%2A?displayProperty=nameWithType