What is the purpose of SortVersion class? How it affects string comparison and ordering operations?

 From the .NET Framework 2.0 Service Pack 1 through the .NET Framework 4, each version of the.NET Framework has included tables that contain sort weights and data on string normalization and that are based on a particular version of Unicode. In the .NET Framework 4.5, the presence of these tables depends on the operating system:

  • On Windows 7 and previous versions of the Windows operating system, the tables continue to be used for comparing and ordering strings.
  • On Windows 8, the .NET Framework delegates string comparison and ordering operations to the operating system.
  • Consequently, the result of a string comparison can depend not only on the .NET Framework version, but also on the operating system version, as the following table shows:
  1. .NET Framework version Operating system Unicode version
  2. .NET Framework 4 All operating systems Unicode 5.0
  3. NET Framework 4.5 Windows 7 Unicode 5.0
  4. NET Framework 4.5 Windows 8 Unicode 6.0
  • On Windows 8, because the version of Unicode used in string comparison and ordering depends on the version of the operating system, the results of string comparison may differ even for applications that run on a specific version of the .NET Framework.
The SortVersion class provides information about the Unicode version used by the .NET Framework for string comparison and ordering. It enables to write applications that can detect and successfully handle changes in the version of Unicode that is used to compare and sort an application’s strings. The following example contains a portion of the source code from an application that uses the SortVersion class to ensure that the native names of RegionInfo objects are ordered appropriately for the current system and current culture.

public class Example : IComparer
{
private const string FILENAME = @"./Regions.dat";
private struct Region
{
internal Region(string id, string name)
{
this.Id = id;
this.NativeName = name;
}
public string Id;
public string NativeName;
public override string ToString()
{
return this.NativeName;
}
}
public static void Main()
{
bool reindex = false;
Region[] regions;
SortVersion ver = null;
// If the data has not been saved, create it.
if (! File.Exists(FILENAME)) {
regions = GenerateData();
ver = CultureInfo.CurrentCulture.CompareInfo.Version;
reindex = true;
}
// Retrieve the existing data.
else {
regions = RestoreData(out ver);
}
// Determine whether the current ordering is valid; if not, reorder.
if (reindex || ver != CultureInfo.CurrentCulture.CompareInfo.Version) {
Array.Sort(regions, new Example());
// Save newly reordered data.
SaveData(regions);
}
// Continue with application...
}
private static Region[] GenerateData()
{
List<Region> regions = new List<Region>();
foreach (var culture in CultureInfo.GetCultures(CultureTypes.AllCultures)) {
if (culture.IsNeutralCulture | culture.Equals(CultureInfo.InvariantCulture))
continue;
RegionInfo region = new RegionInfo(culture.Name);
regions.Add(new Region(region.Name, region.NativeName));
}
return regions.ToArray();
}
private static Region[] RestoreData(out SortVersion ver)
{
List<Region> regions = new List<Region>();
BinaryReader binaryReader = new BinaryReader(File.Open(FILENAME, FileMode.Open));
int sortVer = binaryReader.ReadInt32();
Guid sortId = Guid.Parse(binaryReader.ReadString());
ver = new SortVersion(sortVer, sortId);
string id, name;
while (binaryReader.PeekChar() != -1) {
id = binaryReader.ReadString();
name = binaryReader.ReadString();
regions.Add(new Region(id, name));
}
return regions.ToArray();
}
private static void SaveData(Region[] regions)
{
SortVersion sortVersion = CultureInfo.CurrentCulture.CompareInfo.Version;
BinaryWriter binaryWriter = new BinaryWriter(File.Open(FILENAME, FileMode.Create));
binaryWriter.Write(sortVersion.FullVersion);
binaryWriter.Write(sortVersion.SortId.ToString());
foreach (var region in regions) {
binaryWriter.Write(region.Id);
binaryWriter.Write(region.NativeName);
}
binaryWriter.Close();
}
public int Compare(object o1, object o2)
{
// Assume that all casts succeed.
Region r1 = (Region) o1;
Region r2 = (Region) o2;
return String.Compare(r1.NativeName, r2.NativeName,
StringComparison.CurrentCulture);
}
}

Need Help? Contact Us.

Log in

*
*

Forgot password?

*

New User

*
*
*
*