Search code examples
c#.netsortinglocale

How can I normalise sort order of hypens between machines?


I have a Windows 2019 server (set to en-US for all language settings) for which the following code:

var unsorted = new[] {"Aldi", "Al-Murad Tiles", "AliExpress" };
Console.WriteLine("Unsorted: " + string.Join(',', unsorted));
var sorted = unsorted.OrderBy(x => x);
Console.WriteLine("Sorted: " + string.Join(',', sorted));

Produces:

enter image description here

I have a Windows 11 machine (set to en-GB for all language settings) for which the same code produces:

enter image description here

It makes no difference if I set the culture of the current thread to be the same as the server:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

Does anyone know what settings should be applied to the current thread to make existing code sort the same on the Windows 11 machine as it does on the server?

(worth saying this is an example extracted from a much larger legacy codebase so I'd like to make minimal code changes to the affect the current thread/context/environment to make this sorting work rather than re-factor the existing code)


Solution

  • In .NET 5, Globalisation APIs now use ICU libraries, rather than NLS, on Windows, so if one of your machines is running on .NET 5, and the other is running an earlier version, then this could explain why changing the current's thread's culture info doesn't help at all.

    You can use an Ordinal comparison:

    var sorted = unsorted.OrderBy(x => x, StringComparer.Ordinal);
    

    Alternatively, you can also make your .NET 5 app use NLS by editing runtimeconfig.json

    "configProperties": { "System.Globalization.UseNls": "true" }
    

    Or setting the DOTNET_SYSTEM_GLOBALIZATION_USENLS environment variable.