1

The problem I am trying to solve is to add multiple target frameworks (NET45 before and NETSTANDARD2.0 new) for a common library. The library contains a lot of utility classes to sort strings. I want to find the best way to keep .NET 5.0 applications to have the same sorting results as before. I want to find out what is the best way to proceed.

Here is an example.

Comparing . and - will return a different order in .NET Frameworks 4 and .NET 5. This is a breaking change.

The results in the two runtimes are:

using System;
using System.Globalization;
                    
public class Program
{
    public static void Main()
    {       
        // returns -1 in NET47 but returns 1 in NET5_0
        Console.WriteLine(string.Compare(".", "_", StringComparison.InvariantCulture));
        Console.WriteLine(string.Compare(".", "_", StringComparison.CurrentCulture));       
        var cultureInfo = new CultureInfo("en-US", false);
        Console.WriteLine(string.Compare(".", "_", true, cultureInfo));             
    }
}
tonyjy
  • 1,359
  • 3
  • 12
  • 24
  • 10
    Documentation is [here](https://learn.microsoft.com/en-us/dotnet/standard/base-types/string-comparison-net-5-plus); the reasons is that unicode is complex, and .NET 5 now uses ICU (instead of NLS) to be more correct, even if that means making changes to some results – Marc Gravell Apr 20 '21 at 15:14
  • 5
    Other links: [breaking change](https://learn.microsoft.com/en-us/dotnet/core/compatibility/5.0#globalization) (and [full description](https://learn.microsoft.com/en-us/dotnet/core/compatibility/globalization/5.0/icu-globalization-api)), and [more](https://learn.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu) – canton7 Apr 20 '21 at 15:17
  • 2
    What's the real problem? Your title says why, but the answer to why doesn't help anyone. Do you have code that runs in both frameworks and *thats* the real problem? – Erik Philips Apr 20 '21 at 15:26
  • 5
    If your code doesn't run anymore you can always switch back to the old behavior by setting `System.Globalization.UseNls` to true in your project. – Tim Schmelter Apr 20 '21 at 15:27
  • 2
    Or use `Ordinal`, which is faster as well. What's the *actual* problem? Keep in mind that even in .NET Core 3 the code produced different results on different platforms, which is actually *worse*. With .NET (Core) 5, the same code will behave the same everywher. – Panagiotis Kanavos Apr 20 '21 at 15:42

1 Answers1

3

NLS Determines whether .NET uses National Language Support (NLS) or International Components for Unicode (ICU) globalization APIs for Windows apps. .NET 5.0 and later versions use ICU globalization APIs by default on Windows 10 May 2019 Update and later versions.

  • If you omit this setting, .NET uses ICU globalization APIs by default. This is equivalent to setting the value to false.
                      Setting name                        Values
runtimeconfig.json    System.Globalization.UseNls         false - Use ICU globalization
                                                          true - Use NLS globalization
Environment variable  DOTNET_SYSTEM_GLOBALIZATION_USENLS  false - Use ICU globalization
                                                          true - Use NLS globalization

Source

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • 2
    Or use `Ordinal`. The OP hasn't explained what the problem is, so one can't say what the best option is. – Panagiotis Kanavos Apr 20 '21 at 15:40
  • @PanagiotisKanavos While the OP has not explained the real problem he is facing (I agree with you 100%), it's also important for future users who find this question to know about these settings. – Erik Philips Apr 20 '21 at 18:47
  • 1
    I had no problem understanding what the problem OP was asking about: "Comparing . and - will return a different order in .NET Frameworks 4 and .NET 5." – Lasse V. Karlsen Apr 21 '21 at 18:46
  • Does this work for Linux Containers? I want to use NLS in linux containers too – John Varkey Jul 27 '23 at 13:07