API глобализации используют библиотеки ICU в Windows Server 2019
В .NET 7 и более поздних версиях используются международные компоненты для библиотек Юникода (ICU) для функций глобализации при работе в Windows Server 2019. Выпуски Windows, не являющиеся серверными, используют ICU с .NET 5. Однако .NET 7 представила поддержку загрузки ICU в более ранних клиентских версиях Windows, в частности Windows 10 версий 1703, 1709, 1803 и 1809.
Прежнее поведение
В .NET 5 и .NET 6 библиотеки .NET использовали API-интерфейсы поддержки национальных языков (NLS) для функций глобализации в Windows Server 2019. Например, функции NLS применялись для сравнения строк, получения данных о языке и региональных параметрах, а также для изменения капитализации строк в соответствии с необходимыми языком и региональными параметрами. Это поведение также применяется к клиентским версиям Windows 10, таким как 1703, 1709, 1803 и 1809.
Новое поведение
Начиная с .NET 7, если приложение работает в Windows Server 2019 или windows 10 версии 1703, 1709, 1803 и 1809, библиотеки .NET используют API глобализации ICU по умолчанию. (Версии Windows, отличные от сервера, уже использовали ICU с .NET 5, поэтому для этих версий нет изменений.)
Различия в поведении
Вы можете заметить изменения в приложении, даже если не догадываетесь, что используете средства глобализации. В следующем примере показан один из изменений поведения, которые вы можете увидеть, но есть и другие.
Символ валют
Рассмотрим следующий код, который форматирует строку с помощью указателя формата валюты C
. Язык и региональные параметры текущего потока задаются для языка и региональных параметров, включая только язык, а не страну или регион.
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de");
string text = string.Format("{0:C}", 100);
- В .NET 5 и .NET 6 в Windows Server 2019 или Windows 10 версии 1703, 1709, 1803 и 1809, имеет значение
"100,00 €"
текста. - В .NET 7 в Windows Server 2019 или Windows 10 версии 1703, 1709, 1803 и 1809
"100,00 ¤"
используется международный символ валюты вместо евро. В ICU валюта является свойством страны или региона, а не языка.
Причина изменения
- .NET представил некоторые API, зависящие от библиотек ICU, например TimeZoneInfo.TryConvertIanaIdToWindowsId(String, String). Пользователям, которые хотели использовать такие API в Windows Server 2019, требовалось вручную развернуть библиотеки ICU с двоичными файлами с помощью функции локального приложения ICU. Это не было отличным решением, так как код может находиться в библиотеке, которая не может управлять принудительной установкой библиотек ICU с любым приложением или службой, использующим библиотеку.
- Если Windows Server 2019 автоматически предоставляется облачной платформой (например, Azure), развернутая служба не обязательно знает, что она будет работать на таком сервере. Кроме того, владелец службы должен управлять, если или когда развертывать двоичные файлы ICU. Кроме того, каждая служба, развернутая в облаке с помощью Windows Server 2019, которая хочет использовать новые API,зависящие от ICU .NET, необходимо развернуть двоичные файлы ICU со службой. Это может раздуть размер диска на сервере.
- Некоторые пользователи предпочитают использовать ICU по умолчанию, так как он соответствует стандарту Юникода.
Представленные версии
.NET 7
Рекомендуемое действие
Если вы используете .NET 7 в Windows Server 2019 или Windows 10 клиентских версий 1703, 1709, 1803 или 1809, мы рекомендуем протестировать приложение или службу перед доставкой, чтобы убедиться, что поведение должно быть должным образом и не прерывает работу пользователей.
Если вы хотите продолжать использовать API глобализации NLS, можно задать параметр времени выполнения для отменить изменения этого поведения. Дополнительные сведения о доступных параметрах см. в статье Глобализация .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> (если набор содержит строки)