Home > Enterprise >  Unable to reproduce .NET Framework string sort order in .NET 7 even when setting culture explicitly
Unable to reproduce .NET Framework string sort order in .NET 7 even when setting culture explicitly

Time:02-04

I have some legacy code running on .NET Framework 4.8 which sorts some product codes and puts the result in a single database column. This has been running for years accumulating data I can't easily modify. I need it to work the same on .NET 7.

The code is simple:

Code

new[] { "123-CAT", "123CAT" }.OrderBy(x => x).ToArray();

.NET Framework

[ "123CAT", "123-CAT" ]

.NET 7

[ "123-CAT", "123CAT" ]

I need the .NET 7 code to match the .NET Framework result.

So I played around with different cultures thinking it would be simple. To my surprise I could not find any StringComparer culture in .NET 7 that would give the result ["123CAT", "123-CAT"].

These are all the versions I tried. The values marked with *** are the result I want.

// .NET Framework: 123CAT, 123-CAT   ***
// .NET 7        : 123-CAT, 123CAT
var list_default = new[] { "123-CAT", "123CAT" }.OrderBy(x => x).ToArray();

// .NET Framework: 123CAT, 123-CAT   ***
// .NET 7        : 123-CAT, 123CAT
var list_currentCulture = new[] { "123-CAT", "123CAT" }.OrderBy(x => x, StringComparer.CurrentCulture).ToArray();

// .NET Framework: 123CAT, 123-CAT   ***
// .NET 7        : 123-CAT, 123CAT
var list_invariant = new[] { "123-CAT", "123CAT" }.OrderBy(x => x, StringComparer.InvariantCulture).ToArray();

// .NET Framework: 123-CAT, 123CAT
// .NET 7        : 123-CAT, 123CAT
var list_ordinal = new[] { "123-CAT", "123CAT" }.OrderBy(x => x, StringComparer.Ordinal).ToArray();

Based on ASCII table I would expect and probably want the 123-CAT to come first (since the - is an ASCII 45 character) and .NET 7 is doing exactly that. But I need it to match the .NET Framework behavior.

I can get .NET Framework to match .NET 7 (using StringComparer.Ordinal) but not the other way around!

CodePudding user response:

In .NET 5 on Windows was breaking change which switched globalization to ICU from NLS. To revert to NLS on Windows you can add next xml switch to .cpproj:

<ItemGroup>
  <RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>

Read more.

  • Related