全球化 API 在 Windows 10 上使用 ICU 库
当在 Windows 10 2019 年 5 月更新或更高版本上运行时,.NET 5 及更高版本使用 Unicode 国际组件 (ICU) 库来实现全球化功能。
更改描述
在 .NET Core 1.0 - 3.1 和 .NET Framework 4 及更高版本中,.NET 库使用本地语言支持 (NLS) API 来实现 Windows 上的全球化功能。 例如,NLS 函数用于比较字符串,获取区域性信息,并在适当的区域中执行字符串大小写。
从 .NET 5 开始,如果应用在 Windows 10 2019 年 5 月更新或更高版本上运行,.NET 库将默认使用 ICU 全球化 API。
注意
Windows 10 2019 年 5 月更新及更高版本随 ICU 本机库一起提供。 如果 .NET 运行时无法加载 ICU,它将改用 NLS。
行为差异
即使你不知道正在使用全球化设施,你也可能会在应用中看到更改。 本部分列出了你可能会看到的一些行为更改,但还有其他一些行为更改。
String.IndexOf
请考虑使用以下代码,它调用 String.IndexOf(String) 来查找字符串中的换行符索引。
string s = "Hello\r\nworld!";
int idx = s.IndexOf("\n");
Console.WriteLine(idx);
- 在 .NET Core 3.1 和 Windows 上的更早版本中,代码片段打印
6
。 - 在 Windows 10 2019 年 5 月更新和更高版本上的 .NET 5 中,代码片段打印
-1
。 - 在 .NET 6 及更高版本中,代码片段会打印
6
,但仍会使用 ICU 库。
若要通过执行序号搜索而不是区分区域性的搜索来修复此代码,请调用 IndexOf(String, StringComparison) 重载,并传入 StringComparison.Ordinal 作为参数。
可以运行代码分析规则 CA1307:为了清晰起见,请指定 StringComparison 和 CA1309:使用序号 StringComparison 在代码中查找这些调用站点。
有关详细信息,请参阅在 .NET 5 及更高版本中比较字符串时的行为更改。
货币符号
请考虑使用以下代码,它使用货币格式说明符 C
设置字符串格式。 当前线程的区域性设置为仅包括语言(而非国家或地区)的区域性。
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de");
string text = string.Format("{0:C}", 100);
- 在 Windows 上的 .NET Core 3.1 及更早版本中,文本的值为
"100,00 €"
。 - 在 Windows 19H1 和更高版本上的 .NET 5 及更高版本中,文本值为
"100,00 ¤"
,它使用国际货币符号而不是欧元。 在 ICU 中,这种设计是指,货币是国家或地区的属性,而不是语言。
星期几的缩写
DateTimeFormatInfo.GetShortestDayName(DayOfWeek) 方法用于获取周中指定日期的最短日期缩写名称。
- 在 Windows 上的 .NET Core 3.1 及更早版本中,这些星期几的缩写由两个字符组成,例如“Su”。
- 在 .NET 5 及更高版本中,这些星期几缩写仅由一个字符组成,例如“S”。
更改原因
引入此更改是为了统一所有支持的操作系统上的 .NET 的全球化行为。 它还能让应用程序捆绑自己的全球化库,而不是依赖于操作系统的内置库。
引入的版本
.NET 5.0
建议操作
开发人员一方不需要执行任何操作。 但是,如果你想要继续使用 NLS 全球化 API,则可以将运行时开关设置为还原到该行为。 有关可用开关的详细信息,请参阅 .NET 全球化和 ICU 一文。
受影响的 API
- System.Span<T>
- System.String
- System.Globalization 命名空间中的大多数类型
- System.Array.Sort(对字符串数组进行排序时)
- System.Collections.Generic.List<T>.Sort()(当列表元素为字符串时)
- System.Collections.Generic.SortedDictionary<TKey,TValue>(当键为字符串时)
- System.Collections.Generic.SortedList<TKey,TValue>(当键为字符串时)
- System.Collections.Generic.SortedSet<T>(当集包含字符串时)