Skip to main content
.NET Framework Class Library
SortKey Class

Represents the result of mapping a string to its sort key.

Inheritance Hierarchy
SystemObject
  System.GlobalizationSortKey

Namespace:   System.Globalization
Assembly:  mscorlib (in mscorlib.dll)
Syntax
<[%$TOPIC/s21ssexs_en-us_VS_110_2_0_0_0_0%]> _
<[%$TOPIC/s21ssexs_en-us_VS_110_2_0_0_0_1%](True)> _
Public Class SortKey
[[%$TOPIC/s21ssexs_en-us_VS_110_2_0_1_0_0%]]
[[%$TOPIC/s21ssexs_en-us_VS_110_2_0_1_0_1%](true)]
public class SortKey
[[%$TOPIC/s21ssexs_en-us_VS_110_2_0_2_0_0%]]
[[%$TOPIC/s21ssexs_en-us_VS_110_2_0_2_0_1%](true)]
public ref class SortKey
[<[%$TOPIC/s21ssexs_en-us_VS_110_2_0_3_0_0%]>]
[<[%$TOPIC/s21ssexs_en-us_VS_110_2_0_3_0_1%](true)>]
type SortKey =  class end
public class SortKey

The SortKey type exposes the following members.

Properties
  NameDescription
Public property KeyDataGets the byte array representing the current SortKey object.
Public property OriginalStringGets the original string used to create the current SortKey object.
Top
Methods
  NameDescription
Public method Static member CompareCompares two sort keys.
Public method EqualsDetermines whether the specified object is equal to the current SortKey object. (Overrides ObjectEquals(Object).)
Protected method FinalizeAllows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.)
Public method GetHashCodeServes as a hash function for the current SortKey object that is suitable for hashing algorithms and data structures such as a hash table. (Overrides ObjectGetHashCode.)
Public method GetTypeGets the Type of the current instance. (Inherited from Object.)
Protected method MemberwiseCloneCreates a shallow copy of the current Object. (Inherited from Object.)
Public method ToStringReturns a string that represents the current SortKey object. (Overrides ObjectToString.)
Top
Remarks

A culture-sensitive comparison of two strings depends on each character in the strings having several categories of sort weights, including script, alphabetic, case, and diacritic weights. A sort key serves as the repository of these weights for a particular string.

The CompareInfoGetSortKey method returns an instance of the SortKey class that reflects the culture-sensitive mapping of characters in a specified string. The value of a SortKey object is its key data, which is returned by the KeyData property. This key data consists of a series of bytes that encode the string, culture-specific sorting rules, and user-specified comparison options. A comparison using sort keys consists of a bitwise comparison of the corresponding key data in each sort key. For example, if you create a sort key by calling the GetSortKey(String, CompareOptions) method with a value of CompareOptionsIgnoreCase, a string comparison operation that uses the sort key is case-insensitive.

After you create a sort key for a string, you compare sort keys by calling the static SortKeyCompare method. This method performs a simple byte-by-byte comparison, so it is much faster than the StringCompare or CompareInfoCompare method.

Performance considerations

When performing a string comparison, the Compare and CompareInfoCompare methods yield the same results, but they target different scenarios.

At a high level, the CompareInfoCompare method generates the sort key for each string, performs the comparison, and then discards the sort key and returns the result of the comparison. However, the CompareInfoCompare method actually doesn't generate an entire sort key to perform the comparison. Instead, the method generates the key data for each text element (that is, base character, surrogate pair, or combining character sequence) in each string. The method then compares the key data for the corresponding text elements. The operation terminates as soon as the ultimate result of the comparison is determined. Sort key information is computed, but no SortKey object is created. This strategy is economical in terms of performance if both strings are compared once, but becomes expensive if the same strings are compared many times.

The Compare method requires generation of a SortKey object for each string before performing the comparison. This strategy is expensive in terms of performance for the first comparison because of the time and memory invested to generate the SortKey objects. However, it becomes economical if the same sort keys are compared many times.

For example, suppose you write an application that searches a database table for the row in which the string-based index column matches a specified search string. The table contains thousands of rows, and comparing the search string to the index in each row will take a long time. Therefore, when the application stores a row and its index column, it also generates and stores the sort key for the index in a column dedicated to improving search performance. When the application searches for a target row, it compares the sort key for the search string to the sort key for the index string, instead of comparing the search string to the index string.

Security considerations

The CompareInfoGetSortKey(String, CompareOptions) method returns a SortKey object with the value based on a specified string and CompareOptions value, and the culture associated with the underlying CompareInfo object. If a security decision depends on a string comparison or case change, you should use the CompareInfoGetSortKey(String, CompareOptions) method of the invariant culture to ensure that the behavior of the operation is consistent, regardless of the culture settings of the operating system.

Use the following steps to obtain a sort key:

  1. Retrieve the invariant culture from the CultureInfoInvariantCulture property.

  2. Retrieve a CompareInfo object for the invariant culture from the CultureInfoCompareInfo property.

  3. Call the CompareInfoGetSortKey(String, CompareOptions) method.

Working with the value of a SortKey object is equivalent to calling the Windows LCMapString method with the LCMAP_SORTKEY value specified. However, for the SortKey object, the sort keys for English characters precede the sort keys for Korean characters.

SortKey objects can be serialized, but only so that they can cross AppDomain objects. If an application serializes a SortKey object, the application must regenerate all the sort keys when there is a new version of the .NET Framework.

For more information about sort keys, see Unicode Technical Standard #10, "Unicode Collation Algorithm" on the Unicode Consortium website.

Examples

The following example compares the string "llama" using the "en-US" and "es-ES" cultures, and the "en-US" and "es-ES" traditional cultures.

Imports System
Imports System.Globalization

Public Class SamplesSortKey

   Public Shared Sub Main()

      ' Creates a SortKey using the en-US culture. 
      Dim myComp_enUS As CompareInfo = New CultureInfo("en-US", False).CompareInfo
      Dim mySK1 As SortKey = myComp_enUS.GetSortKey("llama")

      ' Creates a SortKey using the es-ES culture with international sort. 
      Dim myComp_esES As CompareInfo = New CultureInfo("es-ES", False).CompareInfo
      Dim mySK2 As SortKey = myComp_esES.GetSortKey("llama")

      ' Creates a SortKey using the es-ES culture with traditional sort. 
      Dim myComp_es As CompareInfo = New CultureInfo(&H40A, False).CompareInfo
      Dim mySK3 As SortKey = myComp_es.GetSortKey("llama")

      ' Compares the en-US SortKey with each of the es-ES SortKey objects.
      Console.WriteLine("Comparing ""llama"" in en-US and in es-ES with international sort : {0}", SortKey.Compare(mySK1, mySK2))
      Console.WriteLine("Comparing ""llama"" in en-US and in es-ES with traditional sort   : {0}", SortKey.Compare(mySK1, mySK3))

   End Sub 'Main 

End Class 'SamplesSortKey


'This code produces the following output. 
' 
'Comparing "llama" in en-US and in es-ES with international sort : 0 
'Comparing "llama" in en-US and in es-ES with traditional sort   : -1
using System;
using System.Globalization;

public class SamplesSortKey  {

   public static void Main()  {

      // Creates a SortKey using the en-US culture.
      CompareInfo myComp_enUS = new CultureInfo("en-US",false).CompareInfo;
      SortKey mySK1 = myComp_enUS.GetSortKey( "llama" );

      // Creates a SortKey using the es-ES culture with international sort.
      CompareInfo myComp_esES = new CultureInfo("es-ES",false).CompareInfo;
      SortKey mySK2 = myComp_esES.GetSortKey( "llama" );

      // Creates a SortKey using the es-ES culture with traditional sort.
      CompareInfo myComp_es   = new CultureInfo(0x040A,false).CompareInfo;
      SortKey mySK3 = myComp_es.GetSortKey( "llama" );

      // Compares the en-US SortKey with each of the es-ES SortKey objects.
      Console.WriteLine( "Comparing \"llama\" in en-US and in es-ES with international sort : {0}", SortKey.Compare( mySK1, mySK2 ) );
      Console.WriteLine( "Comparing \"llama\" in en-US and in es-ES with traditional sort   : {0}", SortKey.Compare( mySK1, mySK3 ) );

   }

}

/*
This code produces the following output.

Comparing "llama" in en-US and in es-ES with international sort : 0
Comparing "llama" in en-US and in es-ES with traditional sort   : -1
*/
using namespace System;
using namespace System::Globalization;
int main()
{

   // Creates a SortKey using the en-US culture.
   CultureInfo^ MyCI = gcnew CultureInfo( "en-US",false );
   CompareInfo^ myComp_enUS = MyCI->CompareInfo;
   SortKey^ mySK1 = myComp_enUS->GetSortKey( "llama" );

   // Creates a SortKey using the es-ES culture with international sort.
   MyCI = gcnew CultureInfo( "es-ES",false );
   CompareInfo^ myComp_esES = MyCI->CompareInfo;
   SortKey^ mySK2 = myComp_esES->GetSortKey( "llama" );

   // Creates a SortKey using the es-ES culture with traditional sort.
   MyCI = gcnew CultureInfo( 0x040A,false );
   CompareInfo^ myComp_es = MyCI->CompareInfo;
   SortKey^ mySK3 = myComp_es->GetSortKey( "llama" );

   // Compares the en-US SortKey with each of the es-ES SortKey objects.
   Console::WriteLine( "Comparing \"llama\" in en-US and in es-ES with international sort : {0}", SortKey::Compare( mySK1, mySK2 ) );
   Console::WriteLine( "Comparing \"llama\" in en-US and in es-ES with traditional sort   : {0}", SortKey::Compare( mySK1, mySK3 ) );
}

/*
This code produces the following output.

Comparing S"llama" in en-US and in es-ES with international sort : 0
Comparing S"llama" in en-US and in es-ES with traditional sort   : -1
*/

The following example shows how you can use the SortKey class to improve performance in an application that relies extensively on sorting and searching a large array. The example creates an unordered array of names, which in this case has 13 elements. It then stores the sort key of each name in a parallel array, which it passes to the ArraySort(Array, Array) method. The result is a sorted array. The example then searches the array for three strings. For each search string, it calls the CompareInfoGetSortKey(String, CompareOptions) method to retrieve the string's sort key, and then calls the ArrayFindIndex method to retrieve the index of that sort key in the array of sort keys. Because the name and sort key arrays are parallel, the returned index is also the index of the name in the names array.

Imports System.Globalization

Module Example
   Public Sub Main()
      ' Define names. 
      Dim names() As String = { "Adam", "Ignatius", "Batholomew", 
                                "Gregory", "Clement", "Frances",  
                                "Harold", "Dalmatius", "Edgar",    
                                "John", "Benedict", "Paul", "George" } 
      Dim sortKeys(names.Length - 1) As SortKey
      Dim ci As CompareInfo = CultureInfo.CurrentCulture.CompareInfo

      For ctr As Integer = 0 To names.Length - 1
         sortKeys(ctr) = ci.GetSortKey(names(ctr), CompareOptions.IgnoreCase)         
      Next    

      ' Sort array based on value of sort keys.
      Array.Sort(names, sortKeys)

      Console.WriteLine("Sorted array: ")
      For Each name In names
         Console.WriteLine(name)
      Next          
      Console.WriteLine()

      Dim namesToFind() As String = { "Paul", "PAUL", "Wilberforce" }

      Console.WriteLine("Searching an array:")
      For Each nameToFind In namesToFind
         Dim searchKey As SortKey = ci.GetSortKey(nameToFind, CompareOptions.IgnoreCase)
         Dim index As Integer = Array.FindIndex(sortKeys, 
                                                Function(x) x.Equals(searchKey)) 
         If index >= 0 Then
            Console.WriteLine("{0} found at index {1}: {2}", nameToFind,
                              index, names(index))
         Else
            Console.WriteLine("{0} not found", nameToFind)
         End If                      
      Next                      
   End Sub 
End Module 
' The example displays the following output: 
'       Sorted array: 
'       Adam 
'       Batholomew 
'       Benedict 
'       Clement 
'       Dalmatius 
'       Edgar 
'       Frances 
'       George 
'       Gregory 
'       Harold 
'       Ignatius 
'       John 
'       Paul 
'        
'       Searching an array: 
'       Paul found at index 12: Paul 
'       PAUL found at index 12: Paul 
'       Wilberforce not found
using System;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      // Define names.
      String[] names= { "Adam", "Ignatius", "Batholomew", "Gregory", 
                        "Clement", "Frances", "Harold", "Dalmatius", 
                        "Edgar", "John", "Benedict", "Paul", "George" }; 
      SortKey[] sortKeys = new SortKey[names.Length];
      CompareInfo ci = CultureInfo.CurrentCulture.CompareInfo;

      for (int ctr = 0; ctr < names.Length; ctr++)
         sortKeys[ctr] = ci.GetSortKey(names[ctr], CompareOptions.IgnoreCase);         

      // Sort array based on value of sort keys.
      Array.Sort(names, sortKeys);

      Console.WriteLine("Sorted array: ");
      foreach (var name in names)
         Console.WriteLine(name);

      Console.WriteLine();

      String[] namesToFind = { "Paul", "PAUL", "Wilberforce" };

      Console.WriteLine("Searching an array:");
      foreach (var nameToFind in namesToFind) {
         SortKey searchKey = ci.GetSortKey(nameToFind, CompareOptions.IgnoreCase);
         int index = Array.FindIndex(sortKeys, (x) => x.Equals(searchKey)); 
         if (index >= 0)
            Console.WriteLine("{0} found at index {1}: {2}", nameToFind,
                              index, names[index]);
         else
            Console.WriteLine("{0} not found", nameToFind);
      } 
   }
}
// The example displays the following output: 
//       Sorted array: 
//       Adam 
//       Batholomew 
//       Benedict 
//       Clement 
//       Dalmatius 
//       Edgar 
//       Frances 
//       George 
//       Gregory 
//       Harold 
//       Ignatius 
//       John 
//       Paul 
//        
//       Searching an array: 
//       Paul found at index 12: Paul 
//       PAUL found at index 12: Paul 
//       Wilberforce not found
Version Information

.NET Framework

Supported in: 4.6, 4.5, 4, 3.5, 3.0, 2.0, 1.1

.NET Framework Client Profile

Supported in: 4, 3.5 SP1
Thread Safety
Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.