共用方式為


CultureInfo 類別

本文提供此 API 參考文件的補充備註。

類別 CultureInfo 提供特定文化特性的資訊,例如語言、子語言、國家/地區、行事曆,以及與特定文化特性相關聯的慣例。 這個類別也提供對 、NumberFormatInfoCompareInfoTextInfo 物件之特定文化特性實例的DateTimeFormatInfo存取權。 這些物件包含文化特性特定作業所需的資訊,例如大小寫、格式化日期和數位,以及比較字串。 類別 CultureInfo 會直接或間接由格式化、剖析或操作特定文化特性數據的類別使用,例如 StringDateTimeDateTimeOffset和數值類型。

文化特性名稱和識別碼

類別 CultureInfo 會根據 RFC 4646 指定每個文化特性的唯一名稱。 此名稱是與語言相關聯的 ISO 639 雙字母或三個字母小寫文化特性代碼和與國家或地區相關聯的 ISO 3166 雙字母小寫子文化特性代碼的組合。 此外,對於在 Windows 10 或更新版本下執行的應用程式,支援對應至有效 BCP-47 語言標籤標的文化特性名稱。

注意

當文化特性名稱傳遞至類別建構函式或 例如 CreateSpecificCultureCultureInfo的方法時,其大小寫並不重要。

以 RFC 4646 為基礎的文化特性名稱格式為 languagecode2-country/regioncode2,其中 languagecode2 是雙字母語言代碼,而 country/regioncode2 是雙字母子文化特性代碼。 範例包括ja-JP日文(日本)和en-US英文(美國)。 如果無法使用雙字母語言代碼,則會使用 ISO 639-3 中所定義的三個字母代碼。

某些文化特性名稱也會指定 ISO 15924 腳本。 例如,Cyrl 會指定斯拉夫文腳本,而 Latn 會指定拉丁腳本。 引入文稿的文化功能名稱會使用 模式 languagecode2country/regioncode2scripttag--。 這種文化名稱的範例是 uz-Cyrl-UZ 烏茲別克(烏茲別克州斯拉夫克)。 在 Windows Vista 之前的 Windows 作業系統上,包含腳本的文化特性名稱會使用模式 languagecode2-country/regioncode2-scripttaguz-UZ-Cyrl 例如,針對烏茲別克(烏茲別克州西拉夫文)。

中性文化特性只由雙字母小寫語言代碼指定。 例如, fr 指定法文的中性文化特性,並 de 指定德文的中性文化特性。

注意

有兩個文化特性名稱與這個規則相矛盾。 名為 zh-Hans的中文(簡體)和名為 zh-Hant的中文(繁體中文)是中性文化。 文化特性名稱代表目前的標準,除非您有使用舊名稱和 zh-CHS zh-CHT的原因,否則應該使用 。

文化特性標識碼是標準的國際數值縮寫,而且具有唯一識別其中一個已安裝文化特性所需的元件。 您的應用程式可以使用預先定義的文化特性標識碼或定義自定義標識碼。

命名空間中的 System.Globalization 這個和其他類別會使用某些預先定義的文化特性名稱和標識碼。 如需 Windows 系統的詳細文化特性資訊,請參閱 Windows 支援的語言/區域名稱清單中的語言標記數據行。 文化名稱遵循 BCP 47 定義的標準。

文化特性名稱和標識碼只代表特定計算機上可找到的文化特性子集。 Windows 版本或 Service Pack 可以變更可用的文化特性。 應用程式可以使用 類別來新增自定義文化 CultureAndRegionInfoBuilder 特性。 用戶可以使用 Microsoft Locale Builder 工具來新增自己的自定義文化特性。 Microsoft Locale Builder 是使用 CultureAndRegionInfoBuilder 類別以 Managed 程式代碼撰寫。

數個不同的名稱與文化特性密切相關,特別是與下列類別成員相關聯的名稱:

非變異、中立和特定文化特性

文化特性通常會分成三組:不變異的文化特性、中性文化特性,以及特定文化特性。

不因文化特性而異。 您的應用程式會使用空字串 (“”) 或其標識符來指定不因名稱而異的文化特性。 InvariantCulture 定義不因文化特性而異的實例。 它與英文相關聯,但與任何國家/地區無關。 它幾乎用於命名空間中 Globalization 需要文化特性的任何方法。

中性文化是與語言相關聯的文化特性,但與國家/地區無關。 特定文化特性是與語言和國家/地區相關聯的文化特性。 例如, fr 是法國文化特性的中性名稱,而 fr-FR 是特定法文(法國)文化特性的名稱。 請注意,中文(簡體)和中文(繁體中文)也被視為中性文化。

不建議針對中性文化特性建立類別的 CompareInfo 實例,因為它包含的數據是任意的。 若要顯示和排序數據,請同時指定語言和區域。 此外, Name 針對中性文化特性建立的物件 CompareInfo 屬性只會傳回國家/地區,而且不包含區域。

定義的文化特性具有階層,其中特定文化特性的父系是中性文化特性,而中性文化特性的父系則是不變異的文化特性。 屬性 Parent 包含與特定文化特性相關聯的中性文化特性。 自定義文化特性應定義 Parent 符合此模式的屬性。

如果操作系統中沒有特定文化特性的資源,則會使用相關聯中性文化特性的資源。 如果中性文化特性的資源無法使用,則會使用內嵌在主要元件中的資源。 如需資源後援程序的詳細資訊,請參閱 封裝和部署資源

Windows API 中的地區設定清單與 .NET 所支援的文化特性清單稍有不同。 例如,如果需要與 Windows 的互操作性,透過 p/invoke 機制,應用程式應該使用針對操作系統定義的特定文化特性。 使用特定文化特性可確保與相等 Windows 地區設定的一致性,該地區設定會以與 相同的 LCID地區設定標識符來識別。

DateTimeFormatInfoNumberFormatInfo 只能針對不因不因文化特性或特定文化特性而建立 ,而不是針對中性文化特性建立 。

如果 DateTimeFormatInfo.Calendar 是 , TaiwanCalendarThread.CurrentCulture 未設定為 zh-TW,則 DateTimeFormatInfo.NativeCalendarNameDateTimeFormatInfo.GetEraName,並 DateTimeFormatInfo.GetAbbreviatedEraName 傳回空字串串 (“” )。

自定義文化特性

在 Windows 上,您可以建立自訂地區設定。 如需詳細資訊,請參閱 自定義地區設定

CultureInfo 和文化數據

.NET 會根據實作、平臺和版本,從各種來源的其中一個衍生其文化數據:

  • 在 Unix 平臺或 Windows 10 和更新版本上執行的所有 .NET (Core) 版本中,文化特性數據是由 Unicode(ICU) 連結庫的國際元件所提供。 ICU 連結庫的特定版本取決於個別操作系統。
  • 在 Windows 9 和舊版上執行的所有 .NET (Core) 版本中,文化特性數據是由 Windows 操作系統提供。
  • 在 .NET Framework 4 和更新版本中,文化特性數據是由 Windows 操作系統提供。

因此,特定 .NET 實作、平臺或版本上可用的文化特性可能無法在不同的 .NET 實作、平臺或版本上使用。

某些 CultureInfo 物件會根據基礎平臺而有所不同。 特別是 zh-CN、或中文(簡體、中國)和 zh-TW或中文(傳統、臺灣)是 Windows 系統上的可用文化特性,但它們是 Unix 系統上的別名文化特性。 “zh-CN” 是 “zh-Hans-CN” 文化特性的別名,而 “zh-TW” 是 “zh-Hant-TW” 文化特性的別名。 對方法的呼叫 GetCultures 不會傳回別名文化特性,而且可能會有不同的屬性值,包括不同的文化特性,與 Windows 對應專案不同 Parentzh-CN針對 和 zh-TW 文化特性,這些差異包括下列各項:

  • 在 Windows 系統上,“zh-CN” 文化特性的父文化是 “zh-Hans”,而 “zh-TW” 文化的父文化則是 “zh-Hant”。 這兩種文化特性的父文化特性都是 「zh」。 在 Unix 系統上,這兩種文化特性的父系都是 “zh”。 這表示,如果您未提供 「zh-CN」 或 「zh-TW」 文化特性的文化特性特定資源,但確實提供中性 「zh-Hans」 或 「zh-Hant」 文化特性的資源,您的應用程式將會載入 Windows 上中性文化特性的資源,而不是在 Unix 上。 在 Unix 系統上,您必須將線程 CurrentUICulture 明確設定為 “zh-Hans” 或 “zh-Hant”。

  • 在 Windows 系統上,呼叫 CultureInfo.Equals 代表 「zh-CN」 文化特性的實例,並將它傳遞為 「zh-Hans-CN」 實例會傳 true回 。 在 Unix 系統上,方法呼叫會傳 false回 。 此行為也適用於在 「zh-TW」 CultureInfo 實例上呼叫 Equals ,並將它傳遞為 「zh-Hant-Tw」 實例。

動態文化特性數據

除了不因文化特性而異,文化特性數據是動態的。 即使預先定義的文化特性也是如此。 例如,國家或地區採用新的貨幣、變更單字的拼字,或變更慣用的行事曆,以及文化特性定義變更來追蹤此專案。 自定義文化特性可能會變更而不通知,而且任何特定文化特性可能會由自定義取代文化特性覆寫。 此外,如下所述,個別使用者可以覆寫文化喜好設定。 應用程式應該一律在運行時間取得文化特性數據。

警告

儲存數據時,您的應用程式應該使用不可變的文化特性、二進位格式或特定不區分文化特性的格式。 根據與非變異文化特性以外的特定文化特性相關聯之目前值所儲存的數據,可能會變成無法讀取,或在該文化特性變更時可能變更意義。

目前的文化特性和目前的UI文化特性

.NET 應用程式中的每個線程都有目前的文化特性和目前的UI文化特性。 目前的文化特性會決定日期、時間、數位和貨幣值的格式化慣例、文字的排序順序、大小寫慣例,以及字串的比較方式。 目前的UI文化特性可用來在運行時間擷取特定文化特性的資源。

注意

如需如何根據每個線程決定目前和目前UI文化特性的資訊,請參閱 文化特性和線程 一節。 如需目前和目前UI文化特性如何決定於新應用程式域中執行的線程,以及跨應用程式域界限的線程,請參閱 文化特性和應用程式域一 節。 如需如何決定目前和目前UI文化特性之線程執行以工作為基礎的異步操作的相關信息,請參閱 文化特性和工作型異步操作 一節。

如需目前文化特性的詳細資訊,請參閱 CultureInfo.CurrentCulture 屬性。 如需目前 UI 文化特性的詳細資訊,請參閱 CultureInfo.CurrentUICulture 屬性主題。

擷取目前和目前的UI文化特性

您可以透過下列兩種方式之一 CultureInfo 取得代表目前文化特性的物件:

下列範例會擷取這兩個屬性值、比較它們以顯示它們是否相等,並顯示目前文化特性的名稱。

using System;
using System.Globalization;
using System.Threading;

public class CurrentCultureEx
{
    public static void Main()
    {
        CultureInfo culture1 = CultureInfo.CurrentCulture;
        CultureInfo culture2 = Thread.CurrentThread.CurrentCulture;
        Console.WriteLine("The current culture is {0}", culture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          culture1 == culture2);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The two CultureInfo objects are equal: True

您可以透過下列兩種方式之一 CultureInfo 取得代表目前UI文化特性的物件:

下列範例會擷取這兩個屬性值、比較它們以顯示它們相等,並顯示目前UI文化特性的名稱。

using System;
using System.Globalization;
using System.Threading;

public class CurrentUIEx
{
    public static void Main()
    {
        CultureInfo uiCulture1 = CultureInfo.CurrentUICulture;
        CultureInfo uiCulture2 = Thread.CurrentThread.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", uiCulture1.Name);
        Console.WriteLine("The two CultureInfo objects are equal: {0}",
                          uiCulture1 == uiCulture2);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The two CultureInfo objects are equal: True

設定目前和目前的UI文化特性

若要變更線程的文化特性和UI文化特性,請執行下列動作:

  1. 藉由呼叫CultureInfo類別建構函式並將文化特性的名稱傳遞給該文化特性,來具現化CultureInfo代表該文化特性的物件。 如果新的文化特性與目前的 Windows 文化特性相同,建 CultureInfo(String) 構函式會具現化 CultureInfo 反映使用者覆寫的物件。 建 CultureInfo(String, Boolean) 構函式可讓您指定如果新文化特性與目前的 Windows 文化特性相同,新具現化 CultureInfo 物件是否反映使用者覆寫。

  2. CultureInfo 物件指派給 CultureInfo.CurrentCulture .NET Core 和 .NET Framework 4.6 和更新版本的 或 CultureInfo.CurrentUICulture 屬性。

下列範例會擷取目前的文化特性。 如果它是法國(法國)文化以外的任何東西,它就會將目前的文化變更為法國(法國)。 否則,它會將目前的文化變更為法文(盧森堡)。

using System;
using System.Globalization;

public class ChangeEx1
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentCulture;
        Console.WriteLine("The current culture is {0}", current.Name);
        CultureInfo newCulture;
        if (current.Name.Equals("fr-FR"))
            newCulture = new CultureInfo("fr-LU");
        else
            newCulture = new CultureInfo("fr-FR");

        CultureInfo.CurrentCulture = newCulture;
        Console.WriteLine("The current culture is now {0}",
                          CultureInfo.CurrentCulture.Name);
    }
}
// The example displays output like the following:
//     The current culture is en-US
//     The current culture is now fr-FR

下列範例會擷取目前的文化特性。 如果它是斯洛維尼亞(斯洛維尼亞)文化,它把目前的文化改為斯洛維尼亞(斯洛維尼亞)。 否則,它把目前的文化改為克羅埃西亞人(克羅埃西亞)。

using System;
using System.Globalization;

public class ChangeUICultureEx
{
    public static void Main()
    {
        CultureInfo current = CultureInfo.CurrentUICulture;
        Console.WriteLine("The current UI culture is {0}", current.Name);
        CultureInfo newUICulture;
        if (current.Name.Equals("sl-SI"))
            newUICulture = new CultureInfo("hr-HR");
        else
            newUICulture = new CultureInfo("sl-SI");

        CultureInfo.CurrentUICulture = newUICulture;
        Console.WriteLine("The current UI culture is now {0}",
                          CultureInfo.CurrentUICulture.Name);
    }
}
// The example displays output like the following:
//     The current UI culture is en-US
//     The current UI culture is now sl-SI

取得所有文化特性

您可以藉由呼叫 GetCultures 方法,擷取特定文化特性類別或本機計算機上所有文化特性的陣列。 例如,您可以單獨或組合擷取自定義文化特性、特定文化特性或中性文化特性。

下列範例會呼叫 GetCultures 方法兩次,先使用 System.Globalization.CultureTypes 列舉成員擷取所有自定義文化特性,然後使用 System.Globalization.CultureTypes 列舉成員擷取所有取代文化特性。

using System;
using System.Globalization;

public class GetCulturesEx
{
    public static void Main()
    {
        // Get all custom cultures.
        CultureInfo[] custom = CultureInfo.GetCultures(CultureTypes.UserCustomCulture);
        if (custom.Length == 0)
        {
            Console.WriteLine("There are no user-defined custom cultures.");
        }
        else
        {
            Console.WriteLine("Custom cultures:");
            foreach (var culture in custom)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();

        // Get all replacement cultures.
        CultureInfo[] replacements = CultureInfo.GetCultures(CultureTypes.ReplacementCultures);
        if (replacements.Length == 0)
        {
            Console.WriteLine("There are no replacement cultures.");
        }
        else
        {
            Console.WriteLine("Replacement cultures:");
            foreach (var culture in replacements)
                Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName);
        }
        Console.WriteLine();
    }
}
// The example displays output like the following:
//     Custom cultures:
//        x-en-US-sample -- English (United States)
//        fj-FJ -- Boumaa Fijian (Viti)
//
//     There are no replacement cultures.

文化特性和線程

啟動新的應用程式線程時,其目前的文化特性和目前的UI文化特性是由目前的系統文化特性所定義,而不是由目前的線程文化特性所定義。 下列範例會說明其間的差異。 它會將應用程式線程的目前文化特性和目前的UI文化特性設定為法文(法國)文化特性(fr-FR)。 如果目前的文化特性已經是fr-FR,此範例會將它設定為英文 (美國) 文化特性 (en-US)。 它會將三個隨機數顯示為貨幣值,然後建立新的線程,接著再將三個隨機數顯示為貨幣值。 但是,如範例的輸出所示,新線程所顯示的貨幣值不會反映法國(法國)文化特性的格式慣例,與主要應用程式線程的輸出不同。

using System;
using System.Globalization;
using System.Threading;

public class DefaultThreadEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          8,11 €
//          1,48 €
//          8,99 €
//          9,04 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: en-US/en-US
//       Some currency values:
//          $6.72
//          $6.35
//          $2.90
//          $7.72

您可以將代表該文化特性的物件指派 CultureInfoDefaultThreadCurrentCulture 和 屬性,以設定應用程式域中所有線程的文化特性和 DefaultThreadCurrentUICulture UI文化特性。 下列範例會使用這些屬性,以確保預設應用程式域中的所有線程共用相同的文化特性。

using System;
using System.Globalization;
using System.Threading;

public class SetThreadsEx
{
    static Random rnd = new Random();

    public static void Main()
    {
        if (Thread.CurrentThread.CurrentCulture.Name != "fr-FR")
        {
            // If current culture is not fr-FR, set culture to fr-FR.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("fr-FR");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("fr-FR");
        }
        else
        {
            // Set culture to en-US.
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture("en-US");
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture("en-US");
        }
        ThreadProc();

        Thread worker = new Thread(SetThreadsEx.ThreadProc);
        worker.Name = "WorkerThread";
        worker.Start();
    }

    private static void DisplayThreadInfo()
    {
        Console.WriteLine("\nCurrent Thread Name: '{0}'",
                          Thread.CurrentThread.Name);
        Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}",
                          Thread.CurrentThread.CurrentCulture.Name,
                          Thread.CurrentThread.CurrentUICulture.Name);
    }

    private static void DisplayValues()
    {
        // Create new thread and display three random numbers.
        Console.WriteLine("Some currency values:");
        for (int ctr = 0; ctr <= 3; ctr++)
            Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10);
    }

    private static void ThreadProc()
    {
        DisplayThreadInfo();
        DisplayValues();
    }
}
// The example displays output similar to the following:
//       Current Thread Name: ''
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          6,83 €
//          3,47 €
//          6,07 €
//          1,70 €
//
//       Current Thread Name: 'WorkerThread'
//       Current Thread Culture/UI Culture: fr-FR/fr-FR
//       Some currency values:
//          9,54 €
//          9,50 €
//          0,58 €
//          6,91 €

警告

DefaultThreadCurrentCulture雖然 和 DefaultThreadCurrentUICulture 屬性是靜態成員,但它們只會針對設定這些屬性值時目前的應用程式域定義預設文化特性和預設UI文化特性。 如需詳細資訊,請參閱下一節 文化特性和應用程式域

當您將值指派給 DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 屬性時,如果線程尚未明確指派文化特性,則應用程式域中線程的文化特性和UI文化特性也會變更。 不過,這些線程只會在目前應用程式域中執行時反映新的文化特性設定。 如果這些線程在另一個應用程式域中執行,其文化特性會變成為該應用程式域定義的預設文化特性。 因此,我們建議您一律設定主要應用程式線程的文化特性,而不依賴 DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 屬性來變更它。

文化特性和應用程式域

DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 是靜態屬性,只會針對設定或擷取屬性值時目前的應用程式域定義預設文化特性。 下列範例會將預設應用程式域中的預設文化特性和預設UI文化特性設定為法文(法國),然後使用 AppDomainSetup 類別和 AppDomainInitializer 委派,將新應用程式域中的預設文化特性和UI文化特性設定為俄文(俄羅斯)。 接著,單一線程會在每個應用程式域中執行兩種方法。 請注意,不會明確設定線程的文化特性和UI文化特性;它們衍生自線程執行所在的應用程式域的預設文化特性和UI文化特性。 另請注意, DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 屬性會傳回在進行方法呼叫時目前的應用程式域預設值 CultureInfo

using System;
using System.Globalization;

public class Example
{
    public static void Main()
    {
        // Set the default culture and display the current date in the current application domain.
        Info info1 = new Info();
        SetAppDomainCultures("fr-FR");

        // Create a second application domain.
        AppDomainSetup setup = new AppDomainSetup();
        setup.AppDomainInitializer = SetAppDomainCultures;
        setup.AppDomainInitializerArguments = new string[] { "ru-RU" };
        AppDomain domain = AppDomain.CreateDomain("Domain2", null, setup);
        // Create an Info object in the new application domain.
        Info info2 = (Info)domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
                                                           "Info");

        // Execute methods in the two application domains.
        info2.DisplayDate();
        info2.DisplayCultures();

        info1.DisplayDate();
        info1.DisplayCultures();
    }

    public static void SetAppDomainCultures(string[] names)
    {
        SetAppDomainCultures(names[0]);
    }

    public static void SetAppDomainCultures(string name)
    {
        try
        {
            CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CreateSpecificCulture(name);
            CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.CreateSpecificCulture(name);
        }
        // If an exception occurs, we'll just fall back to the system default.
        catch (CultureNotFoundException)
        {
            return;
        }
        catch (ArgumentException)
        {
            return;
        }
    }
}

public class Info : MarshalByRefObject
{
    public void DisplayDate()
    {
        Console.WriteLine("Today is {0:D}", DateTime.Now);
    }

    public void DisplayCultures()
    {
        Console.WriteLine("Application domain is {0}", AppDomain.CurrentDomain.Id);
        Console.WriteLine("Default Culture: {0}", CultureInfo.DefaultThreadCurrentCulture);
        Console.WriteLine("Default UI Culture: {0}", CultureInfo.DefaultThreadCurrentUICulture);
    }
}
// The example displays the following output:
//       Today is 14 октября 2011 г.
//       Application domain is 2
//       Default Culture: ru-RU
//       Default UI Culture: ru-RU
//       Today is vendredi 14 octobre 2011
//       Application domain is 1
//       Default Culture: fr-FR
//       Default UI Culture: fr-FR

如需文化特性和應用程式域的詳細資訊,請參閱應用程式域主題中的 節。

文化特性和以工作為基礎的異步操作

工作為基礎的異步程序設計模式 會使用 TaskTask<TResult> 物件,以異步方式在線程集區線程上執行委派。 特定工作事先執行的特定線程並不知道,但只會在運行時間決定。

對於以 .NET Framework 4.6 或更新版本為目標的應用程式,文化特性是異步操作內容的一部分。 換句話說,異步操作預設會 CurrentCulture 繼承啟動線程的 和 CurrentUICulture 屬性值。 如果目前的文化特性或目前的UI文化特性與系統文化特性不同,則目前的文化特性會跨越線程界限,並成為執行異步操作之線程集區線程的目前文化特性。

下列範例提供一個簡單的範例。 此範例會 Func<TResult> 定義委派 , formatDelegate以傳回格式化為貨幣值的一些數位。 此範例會將目前的系統文化特性變更為法文(法國),或者,如果法文(法國)已經是目前的文化特性,則為英文(美國)。 接著是:

  • 直接叫用委派,讓它在主要應用程式線程上同步執行。
  • 建立工作,以異步方式在線程集區線程上執行委派。
  • 藉由呼叫 Task.RunSynchronously 方法,建立以同步方式在主要應用程式線程上執行委派的工作。

如範例的輸出所示,當目前文化特性變更為法文(法國)時,叫用工作的線程目前文化特性會變成該異步操作的目前文化特性。

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;

public class AsyncCultureEx1
{
    public static void Main()
    {
        decimal[] values = { 163025412.32m, 18905365.59m };
        string formatString = "C2";

        string FormatDelegate()
        {
            string output = $"Formatting using the {CultureInfo.CurrentCulture.Name} " +
            "culture on thread {Thread.CurrentThread.ManagedThreadId}.\n";
            foreach (decimal value in values)
                output += $"{value.ToString(formatString)}   ";

            output += Environment.NewLine;
            return output;
        }

        Console.WriteLine($"The example is running on thread {Thread.CurrentThread.ManagedThreadId}");
        // Make the current culture different from the system culture.
        Console.WriteLine($"The current culture is {CultureInfo.CurrentCulture.Name}");
        if (CultureInfo.CurrentCulture.Name == "fr-FR")
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
        else
            Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR");

        Console.WriteLine($"Changed the current culture to {CultureInfo.CurrentCulture.Name}.\n");

        // Execute the delegate synchronously.
        Console.WriteLine("Executing the delegate synchronously:");
        Console.WriteLine(FormatDelegate());

        // Call an async delegate to format the values using one format string.
        Console.WriteLine("Executing a task asynchronously:");
        var t1 = Task.Run(FormatDelegate);
        Console.WriteLine(t1.Result);

        Console.WriteLine("Executing a task synchronously:");
        var t2 = new Task<string>(FormatDelegate);
        t2.RunSynchronously();
        Console.WriteLine(t2.Result);
    }
}
// The example displays the following output:
//         The example is running on thread 1
//         The current culture is en-US
//         Changed the current culture to fr-FR.
//
//         Executing the delegate synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task asynchronously:
//         Formatting using the fr-FR culture on thread 3.
//         163 025 412,32 €   18 905 365,59 €
//
//         Executing a task synchronously:
//         Formatting using the fr-FR culture on thread 1.
//         163 025 412,32 €   18 905 365,59 €

DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 是個別應用程式域屬性;也就是說,它們會為所有未明確指派特定應用程式域中文化特性的線程建立預設文化特性。 不過,對於以 .NET Framework 4.6 或更新版本為目標的應用程式,即使工作跨越應用程式域界限,呼叫線程的文化特性仍會維持異步工作內容的一部分。

CultureInfo 物件串行化

CultureInfo序列化物件時,實際儲存的所有物件都是 NameUseUserOverride。 它只會在具有相同意義的環境中 Name 成功還原串行化。 下列三個範例顯示為什麼不一定如此:

  • CultureTypes如果 屬性值為 CultureTypes.InstalledWin32Cultures,而且該文化特性第一次在 Windows 作業系統的特定版本中引進,則無法在舊版 Windows 上還原串行化它。 例如,如果在 Windows 10 中引進文化特性,則無法在 Windows 8 上還原串行化。

  • CultureTypes如果值為 CultureTypes.UserCustomCulture,且其還原串行化所在的計算機未安裝此使用者自定義文化特性,則無法還原串行化它。

  • CultureTypes如果值為 CultureTypes.ReplacementCultures,且還原串行化所在的計算機沒有這個取代文化特性,則會還原串行化為相同的名稱,但並非所有相同的特性。 例如,如果 en-US 是計算機 A 上的取代文化特性,但不在電腦 B 上,而且 CultureInfo 如果參照此文化特性的對象在電腦 A 上串行化,並在電腦 B 上還原串行化,則不會傳輸文化特性的自定義特性。 文化特性已成功還原串行化,但意義不同。

控制台 覆寫

使用者可能會選擇透過 控制台 的區域和語言選項部分,覆寫與目前 Windows 文化特性相關聯的某些值。 例如,使用者可能會選擇以不同的格式顯示日期,或使用文化特性預設值以外的貨幣。 一般而言,您的應用程式應該接受這些使用者覆寫。

如果 UseUserOverridetrue 且指定的文化特性符合 Windows 目前的文化特性,CultureInfo則會使用這些覆寫,包括 屬性所DateTimeFormat傳回之實例屬性DateTimeFormatInfo的用戶設定,以及 屬性所NumberFormat傳回之實例的屬性NumberFormatInfo。 如果使用者設定與相關聯的 CultureInfo文化特性不相容,例如,如果選取的行事曆不是 其中 OptionalCalendars一個 ,則方法和屬性值未定義。

替代排序順序

某些文化特性支援多個排序順序。 例如:

  • 西班牙(西班牙)文化特性有兩個排序順序:預設的國際排序順序,以及傳統的排序順序。 當您具現化 CultureInfo 具有 es-ES 文化特性名稱的物件時,會使用國際排序順序。 當您具現化 CultureInfo 具有 es-ES-tradnl 文化特性名稱的物件時,會使用傳統的排序順序。

  • zh-CN (簡體中文,中國)文化支援兩種排序順序:發音(預設值)和筆劃計數。 當您具現化 CultureInfo 具有 zh-CN 文化特性名稱的物件時,會使用預設排序順序。 當您具現化 CultureInfo 具有本機標識碼0x00020804的物件時,字串會依筆劃計數排序。

下表列出支援替代排序順序的文化特性,以及預設和替代排序順序的標識碼。

文化特性名稱 文化特性 預設排序名稱和識別碼 替代排序名稱和識別碼
es-ES 西班牙文 (西班牙) 國際:0x00000C0A 傳統:0x0000040A
zh-TW 中文 (台灣) 筆劃計數:0x00000404 波波莫福:0x00030404
zh-CN 中文 (中國) 發音:0x00000804 筆劃計數:0x00020804
zh-HK 中文 (香港特別行政區) 筆劃計數:0x00000c04 筆劃計數:0x00020c04
zh-SG 中文 (新加坡) 發音:0x00001004 筆劃計數:0x00021004
zh-MO 中文 (澳門特別行政區) 發音:0x00001404 筆劃計數:0x00021404
ja-JP 日文 (日本) 默認值:0x00000411 Unicode:0x00010411
ko-KR 韓文 (韓國) 默認值:0x00000412 韓文 Xwansung - Unicode: 0x00010412
de-DE 德文 (德國) 字典:0x00000407 電話簿排序 DIN: 0x00010407
hu-HU 匈牙利文 (匈牙利) 默認值:0x0000040e 技術排序:0x0001040e
ka-GE 喬治亞文 (喬治亞) 傳統:0x00000437 新式排序:0x00010437

目前的文化特性和UWP應用程式

在 通用 Windows 平台 (UWP) 應用程式中,CurrentCultureCurrentUICulture 屬性都是讀寫的,就像在 .NET Framework 和 .NET Core 應用程式中一樣。 不過,UWP 應用程式可辨識單一文化特性。 CurrentCultureCurrentUICulture 屬性會對應至 Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages 集合中的第一個值。

在 .NET 應用程式中,目前的文化特性是每個線程的設定,而 CurrentCultureCurrentUICulture 屬性只會反映目前線程的文化特性和UI文化特性。 在UWP應用程式中,目前的文化特性會對應至 Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages 集合,這是全域設定。 CurrentCulture設定 或 CurrentUICulture 屬性會變更整個應用程式的文化特性;文化特性不能以每個線程為基礎設定。