全球化 API 在 Windows Server 2019 上使用 ICU 程式庫
.NET 7 和更新版本在 Windows Server 2019 上執行時,使用 International Components for Unicode (ICU) 程式庫取得全球化功能。 自 .NET 5 以來,非伺服器版本的 Windows 一直使用 ICU。 不過,.NET 7 引進了在舊版 Windows 用戶端中載入 ICU 的支援,特別是 Windows 10 版本 1703、1709、1803 和 1809。
先前的行為
在 .NET 5 和 .NET 6 中,.NET 程式庫使用國家語言支援 (NLS) API,在 Windows Server 2019 上提供全球化功能。 例如,使用 NLS 函式來比較字串、取得文化特性資訊,以及在適當的文化特性中執行字串大小寫轉換。 此行為也會套用至 Windows 10 用戶端版本,例如 1703、1709、1803 和 1809。
新的行為
從 .NET 7 開始,如果應用程式在 Windows Server 2019 或 Windows 10 用戶端版本 1703、1709、1803 和 1809 上執行,.NET 連結庫預設會使用 ICU 全球化 API。 (非伺服器 Windows 版本從 .NET 5 開始,即使用 ICU,因此這些版本沒有任何變更。)
行為的差異
即使您不知道您使用的是全球化工具,也可能會在應用程式中看到變更。 下列範例顯示您可能會看到的行為變更之一,但除此之外還有其他變更。
貨幣符號
假設下列程式碼使用貨幣格式規範 C
來設定字串格式。 目前執行緒的文化特性會設定為只包含語言而不包含國家或地區的文化特性。
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("de");
string text = string.Format("{0:C}", 100);
- 在 Windows Server 2019 或 Windows 10 用戶端版本 1703、1709、1803 和 1809 上的 .NET 5 和 .NET 6 中,文字的值是
"100,00 €"
。 - 在 Windows Server 2019 或 Windows 10 用戶端版本 1703、1709、1803 和 1809 上的 .NET 7 中,文字的值是
"100,00 ¤"
,它會使用國際貨幣符號而非歐元。 ICU 的設計是,貨幣為國家或地區的屬性,而不是語言。
變更原因
- .NET 引進了一些相依於 ICU 連結庫的 API,例如 TimeZoneInfo.TryConvertIanaIdToWindowsId(String, String)。 想要在 Windows Server 2019 上使用這類 API 的使用者,必須使用 ICU App Local 功能,手動部署 ICU 程式庫與其二進位檔。 這不是理想的解決方案,因為程式碼所在的程式庫,可能無法控制 ICU 程式庫與使用該程式庫的任何應用程式或服務一起安裝。
- 如果雲端平台 (例如 Azure) 會自動提供 Windows Server 2019,部署的服務就不一定要知道會在這類伺服器上執行。 服務擁有者也必須管理 ICU 二進位檔的時機和方式。 此外,使用 Windows Server 2019 部署到雲端的每個服務,如果要使用相依於 .NET ICU 的新 API,都必須使用服務來部署 ICU 二進位檔。 這可能使在伺服器磁碟上的大小膨脹。
- 某些使用者偏好預設使用 ICU,因為其符合 Unicode Standard。
導入的版本
.NET 7
建議的動作
如果您在 Windows Server 2019 或 Windows 10 用戶端版本 1703、1709、1803 或 1809 上使用 .NET 7,建議您先測試您的應用程式或服務,再將其寄送,以確保行為如預期般運作,且不會中斷任何使用者。
如果您想要繼續使用 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> (集合包含字串)