咨询区
Farhad Zamani:
当我在 .NET Core 3.1
中运行下面代码的时候,程序会返回 6。
class Program{static void Main(string[] args){// .NET Core 3.1string s = "Hello\r\nworld!";int idx = s.IndexOf("\n");Console.WriteLine(idx);}}
但是同样的代码跑在 .NET 5.0
中却是不一样的结果。。。
static void Main(string[] args){// .NET 5.0string s = "Hello\r\nworld!";int idx = s.IndexOf("\n");Console.WriteLine(idx);}
请问一下,为什么会出现如此奇葩的事情?
回答区
Ray:
你的样例代码其实在 MSDN: https://docs.microsoft.com/en-us/dotnet/standard/globalization-localization/globalization-icu 上也提到了,而且也很清楚的告知了如何去解决及如何恢复到老的版本。
在过去,.NET 的全球化API 在不同的平台上会使用不同的底层工具包,比如:
Unix 上的 全球化API 会调用 ICU 工具包 (International Components for Unicode)
Windows 上的 全球化API 会调用 NLS 工具包 (National Language Support)
不用的工具包呈现的行为肯定会有一些不一样,影响范围大致包括:
本地化和本地化数据
string 的一些操作 (转换,排序,查找)
zone 和 IDN
2019年5月, windows 做了一个补丁升级,让后续的 .NET 全球化API 由原来的 NLS 切换到了 ICU 模式,这就是在后续的 .NET5 表现不一致的根源,如果你想退回到 NLS,需要做如下配置。
修改 project 文件
<ItemGroup><RuntimeHostConfigurationOption Include="System.Globalization.UseNls" Value="true" />
</ItemGroup>
修改 runtimeconfig.json 文件
{"runtimeOptions": {"configProperties": {"System.Globalization.UseNls": true}}
}
新增环境变量 DOTNET_SYSTEM_GLOBALIZATION_USENLS = 1
。
点评区
看样子是打了补丁之后改变了默认的程序行为,还是不要乱升级,弄不好就要进坑了,????????????