C# 意外的字符串.Compare()导致.NET 5

C# 意外的字符串.Compare()导致.NET 5,c#,.net,.net-core,.net-5,.net-standard-2.0,C#,.net,.net Core,.net 5,.net Standard 2.0,我试图解决的问题是为一个公共库添加多个目标框架(NET45之前的版本和NETSTANDARD2.0新版本)。该库包含许多用于对字符串进行排序的实用程序类。我想找到保持.NET5.0应用程序具有与以前相同的排序结果的最佳方法。我想找出最好的方法 这里有一个例子 比较和-将在.NET Framework 4和.NET Framework 5中返回不同的顺序。这是一个突破性的变化 两个运行时中的结果是: .NET Framework 4.7:-1,意思是- .NET 5.0:1,意思是- 免入

我试图解决的问题是为一个公共库添加多个目标框架(NET45之前的版本和NETSTANDARD2.0新版本)。该库包含许多用于对字符串进行排序的实用程序类。我想找到保持.NET5.0应用程序具有与以前相同的排序结果的最佳方法。我想找出最好的方法

这里有一个例子

比较
-
将在.NET Framework 4和.NET Framework 5中返回不同的顺序。这是一个突破性的变化

两个运行时中的结果是:

  • .NET Framework 4.7:-1,意思是
    -

  • .NET 5.0:1,意思是
    -

免入息审查 确定.NET是为Windows应用程序使用国家语言支持(NLS)还是Unicode(ICU)全球化API使用国际组件。NET 5.0及更高版本在Windows 10 2019年5月更新及更高版本上默认使用ICU全球化API

  • 如果省略此设置,.NET默认使用ICU全球化API。这相当于将该值设置为false

NLS 确定.NET是为Windows应用程序使用国家语言支持(NLS)还是Unicode(ICU)全球化API使用国际组件。NET 5.0及更高版本在Windows 10 2019年5月更新及更高版本上默认使用ICU全球化API

  • 如果省略此设置,.NET默认使用ICU全球化API。这相当于将该值设置为false

文件是;原因是unicode是复杂的,而.NET5现在使用ICU(而不是NLS)更为正确,即使这意味着对某些结果和其他链接进行更改:(和),那么真正的问题是什么?你的标题说明了为什么,但为什么的答案对任何人都没有帮助。您是否有在两个框架中都运行的代码,这才是真正的问题?如果您的代码不再运行,您可以通过在项目中将
System.Globalization.UseNls
设置为true来切换回旧行为。或者使用
Ordinal
,这也会更快。实际的问题是什么?请记住,即使在.NETCore3中,代码也会在不同的平台上产生不同的结果,这实际上更糟糕。在.NET(Core)5中,相同的代码在任何地方的行为都是相同的;原因是unicode是复杂的,而.NET5现在使用ICU(而不是NLS)更为正确,即使这意味着对某些结果和其他链接进行更改:(和),那么真正的问题是什么?你的标题说明了为什么,但为什么的答案对任何人都没有帮助。您是否有在两个框架中都运行的代码,这才是真正的问题?如果您的代码不再运行,您可以通过在项目中将
System.Globalization.UseNls
设置为true来切换回旧行为。或者使用
Ordinal
,这也会更快。实际的问题是什么?请记住,即使在.NETCore3中,代码也会在不同的平台上产生不同的结果,这实际上更糟糕。在.NET(Core)5中,相同的代码在任何地方的行为都是相同的。或者使用
Ordinal
。OP没有解释问题是什么,所以不能说最好的选择是什么。@PanagiotisKanavos虽然OP没有解释他所面临的真正问题(我100%同意你的看法),但对于发现这个问题的未来用户来说,了解这些设置也很重要。我理解OP所问的问题没有问题:“比较。和-将在.NET Frameworks 4和.NET 5中返回不同的顺序。”或使用
序数
。OP没有解释问题是什么,因此不能说最好的选择是什么。@PanagiotisKanavos,而OP没有解释他面临的真正问题(我100%同意你),对于发现此问题的未来用户来说,了解这些设置也很重要。我完全理解OP提出的问题:“比较”。和-将在.NET Framework 4和.NET Framework 5中返回不同的顺序。”
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));             
    }
}
                      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