CultureInfo 類別

定義

提供有關特定文化特性 (Culture) 的資訊 (文化特性在 Unmanaged 程式碼開發中稱為「地區設定」(Locale))。 這項資訊包含文化特性的名稱、書寫系統、使用的曆法、字串的排序次序,以及日期和數字的格式。

public ref class CultureInfo : IFormatProvider
public ref class CultureInfo : ICloneable, IFormatProvider
public class CultureInfo : IFormatProvider
public class CultureInfo : ICloneable, IFormatProvider
[System.Serializable]
public class CultureInfo : ICloneable, IFormatProvider
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public class CultureInfo : ICloneable, IFormatProvider
type CultureInfo = class
    interface IFormatProvider
type CultureInfo = class
    interface ICloneable
    interface IFormatProvider
[<System.Serializable>]
type CultureInfo = class
    interface ICloneable
    interface IFormatProvider
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type CultureInfo = class
    interface ICloneable
    interface IFormatProvider
Public Class CultureInfo
Implements IFormatProvider
Public Class CultureInfo
Implements ICloneable, IFormatProvider
繼承
CultureInfo
屬性
實作

範例

下列範例示範如何為 CultureInfo 西班牙文 (西班牙) 使用國際排序和另一個 CultureInfo 具有傳統排序的物件來建立物件。

using namespace System;
using namespace System::Collections;
using namespace System::Globalization;
int main()
{
   
   // Creates and initializes the CultureInfo which uses the international sort.
   CultureInfo^ myCIintl = gcnew CultureInfo( "es-ES",false );
   
   // Creates and initializes the CultureInfo which uses the traditional sort.
   CultureInfo^ myCItrad = gcnew CultureInfo( 0x040A,false );
   
   // Displays the properties of each culture.
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "PROPERTY", "INTERNATIONAL", "TRADITIONAL" );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "CompareInfo", myCIintl->CompareInfo, myCItrad->CompareInfo );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "DisplayName", myCIintl->DisplayName, myCItrad->DisplayName );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "EnglishName", myCIintl->EnglishName, myCItrad->EnglishName );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "IsNeutralCulture", myCIintl->IsNeutralCulture, myCItrad->IsNeutralCulture );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "IsReadOnly", myCIintl->IsReadOnly, myCItrad->IsReadOnly );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "LCID", myCIintl->LCID, myCItrad->LCID );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "Name", myCIintl->Name, myCItrad->Name );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "NativeName", myCIintl->NativeName, myCItrad->NativeName );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "Parent", myCIintl->Parent, myCItrad->Parent );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "TextInfo", myCIintl->TextInfo, myCItrad->TextInfo );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "ThreeLetterISOLanguageName", myCIintl->ThreeLetterISOLanguageName, myCItrad->ThreeLetterISOLanguageName );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "ThreeLetterWindowsLanguageName", myCIintl->ThreeLetterWindowsLanguageName, myCItrad->ThreeLetterWindowsLanguageName );
   Console::WriteLine( "{0,-31}{1,-47}{2,-25}", "TwoLetterISOLanguageName", myCIintl->TwoLetterISOLanguageName, myCItrad->TwoLetterISOLanguageName );
   Console::WriteLine();
   
   // Compare two strings using myCIintl -> 
   Console::WriteLine( "Comparing \"llegar\" and \"lugar\"" );
   Console::WriteLine( "   With myCIintl -> CompareInfo -> Compare: {0}", myCIintl->CompareInfo->Compare( "llegar", "lugar" ) );
   Console::WriteLine( "   With myCItrad -> CompareInfo -> Compare: {0}", myCItrad->CompareInfo->Compare( "llegar", "lugar" ) );
}

/*
This code produces the following output.

PROPERTY                       INTERNATIONAL                                  TRADITIONAL              
CompareInfo                    CompareInfo - es-ES                            CompareInfo - es-ES_tradnl
DisplayName                    Spanish (Spain)                                Spanish (Spain)          
EnglishName                    Spanish (Spain, International Sort)            Spanish (Spain, Traditional Sort)
IsNeutralCulture               False                                          False                    
IsReadOnly                     False                                          False                    
LCID                           3082                                           1034                     
Name                           es-ES                                          es-ES                    
NativeName                     Español (España, alfabetización internacional) Español (España, alfabetización tradicional)
Parent                         es                                             es                       
TextInfo                       TextInfo - es-ES                               TextInfo - es-ES_tradnl  
ThreeLetterISOLanguageName     spa                                            spa                      
ThreeLetterWindowsLanguageName ESN                                            ESP                      
TwoLetterISOLanguageName       es                                             es                       

Comparing "llegar" and "lugar"
   With myCIintl -> CompareInfo -> Compare: -1
   With myCItrad -> CompareInfo -> Compare: 1

*/
using System;
using System.Collections;
using System.Globalization;

public class SamplesCultureInfo
{

   public static void Main()
   {

      // Creates and initializes the CultureInfo which uses the international sort.
      CultureInfo myCIintl = new CultureInfo("es-ES", false);

      // Creates and initializes the CultureInfo which uses the traditional sort.
      CultureInfo myCItrad = new CultureInfo(0x040A, false);

      // Displays the properties of each culture.
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "PROPERTY", "INTERNATIONAL", "TRADITIONAL");
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "CompareInfo", myCIintl.CompareInfo, myCItrad.CompareInfo);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "DisplayName", myCIintl.DisplayName, myCItrad.DisplayName);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "EnglishName", myCIintl.EnglishName, myCItrad.EnglishName);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "IsNeutralCulture", myCIintl.IsNeutralCulture, myCItrad.IsNeutralCulture);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "IsReadOnly", myCIintl.IsReadOnly, myCItrad.IsReadOnly);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "LCID", myCIintl.LCID, myCItrad.LCID);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "Name", myCIintl.Name, myCItrad.Name);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "NativeName", myCIintl.NativeName, myCItrad.NativeName);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "Parent", myCIintl.Parent, myCItrad.Parent);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "TextInfo", myCIintl.TextInfo, myCItrad.TextInfo);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "ThreeLetterISOLanguageName", myCIintl.ThreeLetterISOLanguageName, myCItrad.ThreeLetterISOLanguageName);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "ThreeLetterWindowsLanguageName", myCIintl.ThreeLetterWindowsLanguageName, myCItrad.ThreeLetterWindowsLanguageName);
      Console.WriteLine("{0,-31}{1,-47}{2,-25}", "TwoLetterISOLanguageName", myCIintl.TwoLetterISOLanguageName, myCItrad.TwoLetterISOLanguageName);
      Console.WriteLine();

      // Compare two strings using myCIintl.
      Console.WriteLine("Comparing \"llegar\" and \"lugar\"");
      Console.WriteLine("   With myCIintl.CompareInfo.Compare: {0}", myCIintl.CompareInfo.Compare("llegar", "lugar"));
      Console.WriteLine("   With myCItrad.CompareInfo.Compare: {0}", myCItrad.CompareInfo.Compare("llegar", "lugar"));
   }
}

/*
This code produces the following output.

PROPERTY                       INTERNATIONAL                                  TRADITIONAL
CompareInfo                    CompareInfo - es-ES                            CompareInfo - es-ES_tradnl
DisplayName                    Spanish (Spain)                                Spanish (Spain)
EnglishName                    Spanish (Spain, International Sort)            Spanish (Spain, Traditional Sort)
IsNeutralCulture               False                                          False
IsReadOnly                     False                                          False
LCID                           3082                                           1034
Name                           es-ES                                          es-ES
NativeName                     Español (España, alfabetización internacional) Español (España, alfabetización tradicional)
Parent                         es                                             es
TextInfo                       TextInfo - es-ES                               TextInfo - es-ES_tradnl
ThreeLetterISOLanguageName     spa                                            spa
ThreeLetterWindowsLanguageName ESN                                            ESP
TwoLetterISOLanguageName       es                                             es

Comparing "llegar" and "lugar"
   With myCIintl.CompareInfo.Compare: -1
   With myCItrad.CompareInfo.Compare: 1

*/
Imports System.Collections
Imports System.Globalization

Module Module1

    Public Sub Main()

        ' Creates and initializes the CultureInfo which uses the international sort.
        Dim myCIintl As New CultureInfo("es-ES", False)

        ' Creates and initializes the CultureInfo which uses the traditional sort.
        Dim myCItrad As New CultureInfo(&H40A, False)

        ' Displays the properties of each culture.
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "PROPERTY", "INTERNATIONAL", "TRADITIONAL")
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "CompareInfo", myCIintl.CompareInfo, myCItrad.CompareInfo)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "DisplayName", myCIintl.DisplayName, myCItrad.DisplayName)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "EnglishName", myCIintl.EnglishName, myCItrad.EnglishName)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "IsNeutralCulture", myCIintl.IsNeutralCulture, myCItrad.IsNeutralCulture)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "IsReadOnly", myCIintl.IsReadOnly, myCItrad.IsReadOnly)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "LCID", myCIintl.LCID, myCItrad.LCID)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "Name", myCIintl.Name, myCItrad.Name)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "NativeName", myCIintl.NativeName, myCItrad.NativeName)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "Parent", myCIintl.Parent, myCItrad.Parent)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "TextInfo", myCIintl.TextInfo, myCItrad.TextInfo)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "ThreeLetterISOLanguageName", myCIintl.ThreeLetterISOLanguageName, myCItrad.ThreeLetterISOLanguageName)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "ThreeLetterWindowsLanguageName", myCIintl.ThreeLetterWindowsLanguageName, myCItrad.ThreeLetterWindowsLanguageName)
        Console.WriteLine("{0,-31}{1,-47}{2,-25}", "TwoLetterISOLanguageName", myCIintl.TwoLetterISOLanguageName, myCItrad.TwoLetterISOLanguageName)
        Console.WriteLine()

        ' Compare two strings using myCIintl.
        Console.WriteLine("Comparing ""llegar"" and ""lugar""")
        Console.WriteLine("   With myCIintl.CompareInfo.Compare: {0}", myCIintl.CompareInfo.Compare("llegar", "lugar"))
        Console.WriteLine("   With myCItrad.CompareInfo.Compare: {0}", myCItrad.CompareInfo.Compare("llegar", "lugar"))

    End Sub



'This code produces the following output.
'
'PROPERTY                       INTERNATIONAL                                  TRADITIONAL              
'CompareInfo                    CompareInfo - es-ES                            CompareInfo - es-ES_tradnl
'DisplayName                    Spanish (Spain)                                Spanish (Spain)          
'EnglishName                    Spanish (Spain, International Sort)            Spanish (Spain, Traditional Sort)
'IsNeutralCulture               False                                          False                    
'IsReadOnly                     False                                          False                    
'LCID                           3082                                           1034                     
'Name                           es-ES                                          es-ES                    
'NativeName                     Español (España, alfabetización internacional) Español (España, alfabetización tradicional)
'Parent                         es                                             es                       
'TextInfo                       TextInfo - es-ES                               TextInfo - es-ES_tradnl  
'ThreeLetterISOLanguageName     spa                                            spa                      
'ThreeLetterWindowsLanguageName ESN                                            ESP                      
'TwoLetterISOLanguageName       es                                             es                       
'
'Comparing "llegar" and "lugar"
'   With myCIintl.CompareInfo.Compare: -1
'   With myCItrad.CompareInfo.Compare: 1

End Module

備註

CultureInfo類別會提供文化特性特定的資訊,例如與特定文化特性相關聯的語言、子語言、國家/地區、行事曆和慣例。 這個類別也可讓您存取 DateTimeFormatInfoNumberFormatInfoCompareInfo 和物件的文化特性特定實例 TextInfo 。 這些物件包含文化特性特定作業所需的資訊,例如大小寫、格式化日期和數位,以及比較字串。 CultureInfo類別是直接或間接由格式化、剖析或操作特定文化特性資料的類別(例如 StringDateTime 、和)所使用 DateTimeOffset

本節內容:

文化特性名稱和識別碼
非變異、中性和特定文化特性
自訂文化特性
動態文化特性資料
CultureInfo 和文化特性資料
目前的文化特性和目前的 UI 文化特性
取得所有文化特性
文化特性和執行緒
文化特性和應用程式域
文化特性和以工作為基礎的非同步作業
CultureInfo 物件序列化
主控台覆寫
替代排序次序
文化特性和 Windows 應用程式\

文化特性名稱和識別碼

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

注意

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

以 RFC 4646 為基礎之文化特性名稱的格式為 languagecode2 - country/regioncode2 ,其中 languagecode2 是兩個字母的語言代碼,而 country/regioncode2 是兩個字母的文化特性代碼。 範例包括 ja-JP 日文 (日本) 和 en-US 英文 (美國) 。 如果沒有兩個字母的語言代碼可供使用,則會使用衍生自 ISO 639-2 的三個字母代碼。

某些文化特性名稱也會指定 ISO 15924 腳本。 例如,Cyrl 指定了斯拉夫腳本,而 Latn 指定了拉丁腳本。 包含腳本的文化特性名稱會使用模式 languagecode2 - scripttag - country/regioncode2 。 此類型的文化特性名稱範例 uz-Cyrl-UZ 適用于烏茲別克 (斯拉夫文、烏茲別克) 。 在 Windows Vista 之前 Windows 作業系統上,包含腳本的文化特性名稱會使用模式 languagecode2 - country/regioncode2 - scripttag ,例如, uz-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 是使用類別以 managed 程式碼撰寫的 CultureAndRegionInfoBuilder

有幾個不同的名稱與文化特性緊密相關,尤其是與下列類別成員相關聯的名稱:

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

文化特性通常會分成三個集合:非變異文化特性、中性文化特性和特定文化特性。

不區分文化特性的文化特性不區分文化特性。 您的應用程式會使用空字串 ( "" ) 或其識別碼,依名稱指定非變異文化特性。 InvariantCulture 定義不變文化特性的實例。 它會與英文語言相關聯,但不會與任何國家/地區相關聯。 它幾乎用於 Globalization 命名空間中需要文化特性的任何方法。

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

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

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

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

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

您只能 DateTimeFormatInfo NumberFormatInfo 針對非變異文化特性或特定文化特性(而非中立文化特性)建立或。

如果 DateTimeFormatInfo.Calendar 是, TaiwanCalendar 但不 Thread.CurrentCulture 是設定為 zh-TW ,則會 DateTimeFormatInfo.NativeCalendarName 傳回 DateTimeFormatInfo.GetEraName DateTimeFormatInfo.GetAbbreviatedEraName 空字串 ( "" ) 。

自訂文化特性

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

CultureInfo 和文化特性資料

.NET 會根據執行、平臺和版本,從各種來源中衍生其文化資料:

  • 在 .NET Framework 3.5 及更早版本中,Windows 作業系統和 .NET Framework 都提供文化特性資料。

  • 在 .NET Framework 4 和更新版本中,Windows 作業系統提供文化特性資料。

  • 在 Windows 上執行的所有 .net Core 版本中,Windows 作業系統都會提供文化特性資料。

  • 在 Unix 平臺上執行的所有 .NET Core 版本中,文化特性資料是由 Unicode (ICU) 程式庫的國際元件所提供。 特定版本的 ICU 程式庫取決於個別的作業系統。

基於這個原因,特定 .NET 執行、平臺或版本上的文化特性可能無法在不同的 .NET 執行、平臺或版本上提供使用。

某些 CultureInfo 物件會根據基礎平臺而有所不同。 特別是, zh-CN 或中文 (簡體、中國) 和 zh-TW 或中文 (傳統的臺灣) ,在 Windows 系統上是可用的文化特性,但它們在 Unix 系統上是具有別名的文化特性。 "zh-CN" 是 "zh-Hans-CN" 文化特性的別名,而 "zh-華文" 是 "zh-Zh-hant-華文" 文化特性的別名。 對方法的呼叫不會傳回別名的文化 GetCultures 特性,而且可能會有不同的屬性值,包括不同 Parent 的文化特性,而不是它們的 Windows 對應項。 針對 zh-CNzh-TW 文化特性,這些 differenes 包含下列各項:

  • 在 Windows 系統上,"zh-CN" 文化特性的父文化特性是 "zh-Hans",而 "zh" 文化特性的父文化特性是 "zh-zh-hant"。 這兩種文化特性的父文化特性是 "zh"。 在 Unix 系統上,這兩個文化特性的父系都是 "zh"。 這表示,如果您未針對 "zh-CN" 或 "zh" 文化特性提供文化特性專屬的資源,但卻提供了中性 "zh-Hans" 或 "zh-zh-hant" 文化特性的資源,則您的應用程式將會在 Windows 上載入中性文化特性的資源,但不會在 Unix 上載入。 在 Unix 系統上,您必須將執行緒明確設定 CurrentUICulture 為 "zh-Hans" 或 "zh-zh-hant"。

  • 在 Windows 系統上,呼叫 CultureInfo.Equals 代表 "zh-cn" 文化特性的實例,並將 "zh-Hans-cn" 實例傳遞給它 true 。 在 Unix 系統上,方法呼叫會傳回 false 。 此行為也適用于 Equals 在 "zh" 實例上呼叫 CultureInfo ,並將其傳遞給 "Zh-Zh-hant-隸書" 實例。

動態文化特性資料

文化特性資料是動態的,但不因文化特性而異。 即使是預先定義的文化特性也是如此。 例如,國家或地區採用新的貨幣、變更其單字的拼寫、變更其偏好的行事曆,以及文化特性定義變更來追蹤此情況。 自訂文化特性如有變更,恕不另行通知,且任何特定文化特性可能會由自訂取代文化特性覆寫。 此外,如以下所述,個別使用者可以覆寫文化喜好設定。 應用程式一律會在執行時間取得文化特性資料。

警告

儲存資料時,您的應用程式應該使用不因文化特性而異的文化特性、二進位格式或特定的文化特性獨立格式。 根據與特定文化特性相關聯的目前值(不因文化特性而異)所儲存的資料,可能會變得無法讀取或可能因為文化特性變更而改變。

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

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

注意

如需目前和目前 UI 文化特性如何根據每個執行緒決定的詳細資訊,請參閱 文化特性和執行緒 一節。 如需如何在新的應用程式域中執行的執行緒上,以及跨應用程式域界限的執行緒上,判斷目前和目前 UI 文化特性的相關資訊,請參閱 文化特性和應用程式域 一節。 如需有關如何在執行工作型非同步作業的執行緒上判斷目前和目前的資訊,請參閱文化特性和以工作 為基礎的非同步作業 一節。

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

正在抓取目前和目前的 UI 文化特性

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

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

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

public class Example
{
   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
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Dim culture1 As CultureInfo = CultureInfo.CurrentCulture
      Dim culture2 As CultureInfo = Thread.CurrentThread.CurrentCulture
      Console.WriteLine("The current culture is {0}", culture1.Name)
      Console.WriteLine("The two CultureInfo objects are equal: {0}",
                        culture1.Equals(culture2))
   End Sub
End Module
' 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 Example
{
   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
Imports System.Globalization
Imports System.Threading

Module Example
   Public Sub Main()
      Dim uiCulture1 As CultureInfo = CultureInfo.CurrentUICulture
      Dim uiCulture2 As CultureInfo = Thread.CurrentThread.CurrentUICulture
      Console.WriteLine("The current UI culture is {0}", uiCulture1.Name)
      Console.WriteLine("The two CultureInfo objects are equal: {0}",
                        uiCulture1.Equals(uiCulture2))
   End Sub
End Module
' 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 會將反映使用者覆寫的物件具現化。 如果新的文化特性與目前的 Windows 文化特性相同,則此函式可 CultureInfo(String, Boolean) 讓您指定新具現化的 CultureInfo 物件是否會反映使用者覆寫。

  2. CultureInfo 物件指派給 CultureInfo.CurrentCulture CultureInfo.CurrentUICulture .net Core 和 .NET Framework 4.6 和更新版本上的或屬性。 (在 .NET Framework 4.5.2 和較早的版本上,您可以將 CultureInfo 物件指派給 Thread.CurrentCultureThread.CurrentUICulture 屬性。 )

下列範例會捕獲目前的文化特性。 如果它不是法文 (法國) 文化特性,則會將目前的文化特性變更為法文 (法國) 。 否則,它會將目前的文化特性變更為法文 (盧森堡) 。

using System;
using System.Globalization;

public class Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim current As CultureInfo = CultureInfo.CurrentCulture
      Console.WriteLine("The current culture is {0}", current.Name)
      Dim newCulture As CultureInfo
      If current.Name.Equals("fr-FR") Then
         newCulture = New CultureInfo("fr-LU")
      Else   
         newCulture = new CultureInfo("fr-FR")
      End If
      
      CultureInfo.CurrentCulture = newCulture
      Console.WriteLine("The current culture is now {0}", 
                        CultureInfo.CurrentCulture.Name)   
   End Sub
End Module
' 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 Example
{
   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
Imports System.Globalization

Module Example
   Public Sub Main()
      Dim current As CultureInfo = CultureInfo.CurrentUICulture
      Console.WriteLine("The current UI culture is {0}", current.Name)
      Dim newUICulture As CultureInfo
      If current.Name.Equals("sl-SI") Then
         newUICulture = New CultureInfo("hr-HR")
      Else   
         newUICulture = new CultureInfo("sl-SI")
      End If
      
      CultureInfo.CurrentUICulture = newUICulture
      Console.WriteLine("The current UI culture is now {0}", 
                        CultureInfo.CurrentUICulture.Name)   
   End Sub
End Module
' 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 Example
{
   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.
Imports System.Globalization

Module Example
   Public Sub Main()
      ' Get all custom cultures.
      Dim custom() As CultureInfo = CultureInfo.GetCultures(CultureTypes.UserCustomCulture)
      If custom.Length = 0 Then 
         Console.WriteLine("There are no user-defined custom cultures.")
      Else
         Console.WriteLine("Custom cultures:")
         For Each culture In custom 
            Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName)
         Next       
      End If
      Console.WriteLine()
      
      ' Get all replacement cultures.
      Dim replacements() As CultureInfo = CultureInfo.GetCultures(CultureTypes.ReplacementCultures)
      If replacements.Length = 0 Then 
         Console.WriteLine("There are no replacement cultures.")
      Else 
         Console.WriteLine("Replacement cultures:")
         For Each culture in replacements 
            Console.WriteLine("   {0} -- {1}", culture.Name, culture.DisplayName)    
         Next
      End If
      Console.WriteLine()
   End Sub
End Module
' 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 Example
{
   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
Imports System.Globalization
Imports System.Threading

Module Example
   Dim rnd As New Random()
   
   Public Sub Main()
      If Thread.CurrentThread.CurrentCulture.Name <> "fr-FR" Then
         ' 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")
      End If
      ThreadProc()
          
       Dim worker As New Thread(AddressOf ThreadProc)
       worker.Name = "WorkerThread"
       worker.Start()
   End Sub
   
   Private Sub DisplayThreadInfo()
      Console.WriteLine()
      Console.WriteLine("Current Thread Name: '{0}'", 
                        Thread.CurrentThread.Name)
      Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}", 
                        Thread.CurrentThread.CurrentCulture.Name,
                        Thread.CurrentThread.CurrentUICulture.Name)                        
   End Sub
   
   Private Sub DisplayValues()
      ' Create new thread and display three random numbers.
      Console.WriteLine("Some currency values:")
      For ctr As Integer = 0 To 3
         Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10)                        
      Next
   End Sub
   
   Private Sub ThreadProc()
      DisplayThreadInfo()
      DisplayValues()
   End Sub
End Module
' 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

在 .NET Framework 4.5 之前的 .NET Framework 版本中,確保主要應用程式執行緒與其他所有工作者執行緒共用相同文化特性的最常見方式,是將應用程式範圍文化特性的名稱或 CultureInfo 代表整個應用程式文化特性的物件傳遞給 System.Threading.ParameterizedThreadStart 委派。 下列範例會使用這個方法來確保兩個執行緒所顯示的貨幣值會反映相同文化特性的格式設定慣例。

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

public class Example
{
   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");
      }
      DisplayThreadInfo();
      DisplayValues();

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

   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(Object obj)
   {
      Thread.CurrentThread.CurrentCulture = (CultureInfo) obj;
      Thread.CurrentThread.CurrentUICulture = (CultureInfo) obj;
      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 €
Imports System.Globalization
Imports System.Threading

Module Example
   Dim rnd As New Random()
   
   Public Sub Main()
      If Thread.CurrentThread.CurrentCulture.Name <> "fr-FR" Then
         ' 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")
      End If
      DisplayThreadInfo()
      DisplayValues()
          
       Dim worker As New Thread(AddressOf ThreadProc)
       worker.Name = "WorkerThread"
       worker.Start(Thread.CurrentThread.CurrentCulture)
   End Sub
   
   Private Sub DisplayThreadInfo()
      Console.WriteLine()
      Console.WriteLine("Current Thread Name: '{0}'", 
                        Thread.CurrentThread.Name)
      Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}", 
                        Thread.CurrentThread.CurrentCulture.Name,
                        Thread.CurrentThread.CurrentUICulture.Name)                        
   End Sub
   
   Private Sub DisplayValues()
      ' Create new thread and display three random numbers.
      Console.WriteLine("Some currency values:")
      For ctr As Integer = 0 To 3
         Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10)                        
      Next
   End Sub
   
   Private Sub ThreadProc(obj As Object)
      Thread.CurrentThread.CurrentCulture = CType(obj, CultureInfo)
      Thread.CurrentThread.CurrentUICulture = CType(obj, CultureInfo)
      DisplayThreadInfo()
      DisplayValues()
   End Sub
End Module
' 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 €

您可以藉由呼叫方法,以類似的方式設定執行緒集區執行緒的文化特性和 UI 文化特性 ThreadPool.QueueUserWorkItem(WaitCallback, Object)

從 .NET Framework 4.5 開始,您可以透過將 CultureInfo 表示該文化特性的物件指派給和屬性,更直接地設定應用程式域中所有線程的文化特性和 UI 文化 DefaultThreadCurrentCulture DefaultThreadCurrentUICulture 特性。 下列範例會使用這些屬性,以確保預設應用程式域中的所有線程都共用相同的文化特性。

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

public class Example
{
   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(Example.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 €
Imports System.Globalization
Imports System.Threading

Module Example
   Dim rnd As New Random()
   
   Public Sub Main()
      If Thread.CurrentThread.CurrentCulture.Name <> "fr-FR" Then
         ' 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")
      End If
      ThreadProc()

       Dim worker As New Thread(AddressOf ThreadProc)
       worker.Name = "WorkerThread"
       worker.Start()
   End Sub
   
   Private Sub DisplayThreadInfo()
      Console.WriteLine()
      Console.WriteLine("Current Thread Name: '{0}'", 
                        Thread.CurrentThread.Name)
      Console.WriteLine("Current Thread Culture/UI Culture: {0}/{1}", 
                        Thread.CurrentThread.CurrentCulture.Name,
                        Thread.CurrentThread.CurrentUICulture.Name)                        
   End Sub
   
   Private Sub DisplayValues()
      ' Create new thread and display three random numbers.
      Console.WriteLine("Some currency values:")
      For ctr As Integer = 0 To 3
         Console.WriteLine("   {0:C2}", rnd.NextDouble() * 10)                        
      Next
   End Sub
   
   Private Sub ThreadProc()
      DisplayThreadInfo()
      DisplayValues()
   End Sub
End Module
' 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 €

警告

雖然 DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 屬性是靜態成員,但它們只會定義預設的文化特性和預設 UI 文化特性,只適用于設定這些屬性值時的最新應用程式域。 如需詳細資訊,請參閱下一節: 文化特性和應用程式域

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

文化特性和應用程式域

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

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

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
Imports System.Globalization
Imports System.Reflection
Imports System.Threading

Module Example
   Public Sub Main()
      ' Set the default culture and display the current date in the current application domain.
      Dim info1 As New Info()
      SetAppDomainCultures("fr-FR")
      
      ' Create a second application domain.
      Dim setup As New AppDomainSetup()
      setup.AppDomainInitializer = AddressOf SetAppDomainCultures
      setup.AppDomainInitializerArguments = { "ru-RU" }
      Dim domain As AppDomain = AppDomain.CreateDomain("Domain2", Nothing, setup)
      ' Create an Info object in the new application domain.
      Dim info2 As Info = CType(domain.CreateInstanceAndUnwrap(GetType(Example).Assembly.FullName, 
                                                               "Info"), Info) 

      ' Execute methods in the two application domains.
      info2.DisplayDate()
      info2.DisplayCultures()
      
      info1.DisplayDate()
      info1.DisplayCultures()            
   End Sub
   
   Public Sub SetAppDomainCultures(names() As String)
      SetAppDomainCultures(names(0))
   End Sub
   
   Public Sub SetAppDomainCultures(name As String)
       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 e As CultureNotFoundException
         Return
      Catch e As ArgumentException
         Return
      End Try      
   End Sub
End Module

Public Class Info : Inherits MarshalByRefObject
   Public Sub DisplayDate()
      Console.WriteLine("Today is {0:D}", Date.Now)
   End Sub
   
   Public Sub 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)
   End Sub
End Class
' 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

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

文化特性和以工作為基礎的非同步作業

以工作為 基礎的非同步程式設計模式 會使用 Task 和物件, Task<TResult> 以非同步方式線上程集區執行緒上執行委派。 事先不知道特定工作執行所在的特定執行緒,但是只會在執行時間決定。

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

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

  • 直接叫用委派,使其在主要應用程式執行緒上以同步方式執行。

  • 建立線上程集區執行緒上以非同步方式執行委派的工作。

  • 建立工作,藉由呼叫方法,在主應用程式執行緒上同步執行委派 Task.RunSynchronously

如同範例的輸出所示,當目前的文化特性變更為法文 (法國) 時,以非同步方式叫用工作的執行緒目前文化特性會成為該非同步作業目前的文化特性。

using System;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

[assembly:TargetFramework(".NETFramework,Version=v4.6")]

public class Example
{

   public static void Main()
   {
       decimal[] values = { 163025412.32m, 18905365.59m };
       string formatString = "C2";
       Func<String> formatDelegate = () => { string output = String.Format("Formatting using the {0} culture on thread {1}.\n",
                                                                           CultureInfo.CurrentCulture.Name,
                                                                           Thread.CurrentThread.ManagedThreadId);
                                             foreach (var value in values)
                                                output += String.Format("{0}   ", value.ToString(formatString));

                                             output += Environment.NewLine;
                                             return output;
                                           };

       Console.WriteLine("The example is running on thread {0}",
                         Thread.CurrentThread.ManagedThreadId);
       // Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}",
                         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 {0}.\n",
                         CultureInfo.CurrentCulture.Name);

       // 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 €
Imports System.Globalization
Imports System.Runtime.Versioning
Imports System.Threading
Imports System.Threading.Tasks

<Assembly:TargetFramework(".NETFramework,Version=v4.6")>

Module Example
   Public Sub Main()
       Dim values() As Decimal = { 163025412.32d, 18905365.59d }
       Dim formatString As String = "C2"
       Dim formatDelegate As Func(Of String) = Function()
                                                  Dim output As String = String.Format("Formatting using the {0} culture on thread {1}.",
                                                                                       CultureInfo.CurrentCulture.Name,
                                                                                       Thread.CurrentThread.ManagedThreadId)
                                                  output += Environment.NewLine
                                                  For Each value In values
                                                     output += String.Format("{0}   ", value.ToString(formatString))
                                                  Next 
                                                  output += Environment.NewLine
                                                  Return output
                                               End Function
       
       Console.WriteLine("The example is running on thread {0}", 
                         Thread.CurrentThread.ManagedThreadId)
       ' Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}", 
                         CultureInfo.CurrentCulture.Name)
       If CultureInfo.CurrentCulture.Name = "fr-FR" Then
          Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
       Else
          Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR")
       End If
       Console.WriteLine("Changed the current culture to {0}.",
                         CultureInfo.CurrentCulture.Name)
       Console.WriteLine()                  
       
       ' 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:") 
       Dim t1 = Task.Run(formatDelegate)
       Console.WriteLine(t1.Result)
       
       Console.WriteLine("Executing a task synchronously:")
       Dim t2 = New Task(Of String)(formatDelegate) 
       t2.RunSynchronously()
       Console.WriteLine(t2.Result)
   End Sub
End Module
' 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 Imports the fr-FR culture on thread 1.
'          163 025 412,32 €   18 905 365,59 €
'
'          Executing a task asynchronously:
'          Formatting Imports the fr-FR culture on thread 3.
'          163 025 412,32 €   18 905 365,59 €
'
'          Executing a task synchronously:
'          Formatting Imports the fr-FR culture on thread 1.
'          163 025 412,32 €   18 905 365,59 €

如果應用程式是以 .NET Framework 4.6 之前的 .NET Framework 版本,或針對未以特定 .NET Framework 版本為目標的應用程式,則呼叫執行緒的文化特性不是工作內容的一部分。 相反地,除非明確定義了一個,否則新執行緒的文化特性預設為系統文化特性。 下列範例與上一個範例相同,不同之處在于它缺少 TargetFrameworkAttribute 屬性,說明這一點。 因為執行範例的系統系統文化特性是英文 (美國) ,所以線上程集區執行緒上非同步執行工作的文化特性,而不是 en-US fr-FR

using System;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
       decimal[] values = { 163025412.32m, 18905365.59m };
       string formatString = "C2";
       Func<String> formatDelegate = () => { string output = String.Format("Formatting using the {0} culture on thread {1}.\n",
                                                                           CultureInfo.CurrentCulture.Name,
                                                                           Thread.CurrentThread.ManagedThreadId);
                                             foreach (var value in values)
                                                output += String.Format("{0}   ", value.ToString(formatString));

                                             output += Environment.NewLine;
                                             return output;
                                           };

       Console.WriteLine("The example is running on thread {0}",
                         Thread.CurrentThread.ManagedThreadId);
       // Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}",
                         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 {0}.\n",
                         CultureInfo.CurrentCulture.Name);

       // 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 en-US 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 €
Imports System.Globalization
Imports System.Runtime.Versioning
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
       Dim values() As Decimal = { 163025412.32d, 18905365.59d }
       Dim formatString As String = "C2"
       Dim formatDelegate As Func(Of String) = Function()
                                                  Dim output As String = String.Format("Formatting using the {0} culture on thread {1}.",
                                                                                       CultureInfo.CurrentCulture.Name,
                                                                                       Thread.CurrentThread.ManagedThreadId)
                                                  output += Environment.NewLine
                                                  For Each value In values
                                                     output += String.Format("{0}   ", value.ToString(formatString))
                                                  Next 
                                                  output += Environment.NewLine
                                                  Return output
                                               End Function
       
       Console.WriteLine("The example is running on thread {0}", 
                         Thread.CurrentThread.ManagedThreadId)
       ' Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}", 
                         CultureInfo.CurrentCulture.Name)
       If CultureInfo.CurrentCulture.Name = "fr-FR" Then
          Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
       Else
          Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR")
       End If
       Console.WriteLine("Changed the current culture to {0}.",
                         CultureInfo.CurrentCulture.Name)
       Console.WriteLine()                  
       
       ' 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:") 
       Dim t1 = Task.Run(formatDelegate)
       Console.WriteLine(t1.Result)
       
       Console.WriteLine("Executing a task synchronously:")
       Dim t2 = New Task(Of String)(formatDelegate) 
       t2.RunSynchronously()
       Console.WriteLine(t2.Result)
   End Sub
End Module
' 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 en-US 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 €

針對以 .NET Framework 4.5 和更新版本為目標 .NET Framework 的應用程式,但在 .NET Framework 4.6 之前,您可以使用 DefaultThreadCurrentCultureDefaultThreadCurrentUICulture 屬性,以確保呼叫執行緒的文化特性是線上程集區執行緒上執行的非同步工作中使用。 下列範例與上一個範例相同,不同之處在于它會使用 DefaultThreadCurrentCulture 屬性,以確保執行緒集區執行緒具有與主要應用程式執行緒相同的文化特性。

using System;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   public static void Main()
   {
       decimal[] values = { 163025412.32m, 18905365.59m };
       string formatString = "C2";
       Func<String> formatDelegate = () => { string output = String.Format("Formatting using the {0} culture on thread {1}.\n",
                                                                           CultureInfo.CurrentCulture.Name,
                                                                           Thread.CurrentThread.ManagedThreadId);
                                             foreach (var value in values)
                                                output += String.Format("{0}   ", value.ToString(formatString));

                                             output += Environment.NewLine;
                                             return output;
                                           };

       Console.WriteLine("The example is running on thread {0}",
                         Thread.CurrentThread.ManagedThreadId);
       // Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}",
                         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 {0}.\n",
                         CultureInfo.CurrentCulture.Name);
       CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CurrentCulture;

       // 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 €
Imports System.Globalization
Imports System.Runtime.Versioning
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Public Sub Main()
       Dim values() As Decimal = { 163025412.32d, 18905365.59d }
       Dim formatString As String = "C2"
       Dim formatDelegate As Func(Of String) = Function()
                                                  Dim output As String = String.Format("Formatting using the {0} culture on thread {1}.",
                                                                                       CultureInfo.CurrentCulture.Name,
                                                                                       Thread.CurrentThread.ManagedThreadId)
                                                  output += Environment.NewLine
                                                  For Each value In values
                                                     output += String.Format("{0}   ", value.ToString(formatString))
                                                  Next 
                                                  output += Environment.NewLine
                                                  Return output
                                               End Function
       
       Console.WriteLine("The example is running on thread {0}", 
                         Thread.CurrentThread.ManagedThreadId)
       ' Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}", 
                         CultureInfo.CurrentCulture.Name)
       If CultureInfo.CurrentCulture.Name = "fr-FR" Then
          Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
       Else
          Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR")
       End If
       Console.WriteLine("Changed the current culture to {0}.",
                         CultureInfo.CurrentCulture.Name)
       CultureInfo.DefaultThreadCurrentCulture = CultureInfo.CurrentCulture
       Console.WriteLine()                  
       
       ' 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:") 
       Dim t1 = Task.Run(formatDelegate)
       Console.WriteLine(t1.Result)
       
       Console.WriteLine("Executing a task synchronously:")
       Dim t2 = New Task(Of String)(formatDelegate) 
       t2.RunSynchronously()
       Console.WriteLine(t2.Result)
   End Sub
End Module
' 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 或更新版本為目標的應用程式,呼叫執行緒的文化特性仍會保留在非同步工作的內容中,即使工作跨越應用程式域界限也是一樣。

下列範例顯示呼叫執行緒的文化特性仍維持以工作為基礎之非同步作業的目前文化特性,即使工作執行的方法跨越應用程式域界限也一樣。 它會定義一個 DataRetriever 具有單一方法的類別, GetFormattedNumber 它會傳回1到1000之間的隨機雙精確度浮點數,並格式化為貨幣值。 第一個工作是執行,只是具現化 DataRetriever 實例並呼叫其 GetFormattedNumber 方法。 第二個工作會報告其目前的應用程式域、建立新的應用程式域、 DataRetriever 在新的應用程式域中具現化實例,並呼叫其 GetFormattedNumber 方法。 如範例的輸出所示,在主應用程式域和第二個應用程式域中執行時,目前的文化特性在呼叫執行緒、第一個工作和第二個工作中都保持不變。

using System;
using System.Globalization;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;

[assembly:TargetFramework(".NETFramework,Version=v4.6")]

public class Example
{
   public static void Main()
   {
       string formatString = "C2";
       Console.WriteLine("The example is running on thread {0}",
                         Thread.CurrentThread.ManagedThreadId);
       // Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}",
                         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 {0}.\n",
                         CultureInfo.CurrentCulture.Name);

       // Call an async delegate to format the values using one format string.
       Console.WriteLine("Executing a task asynchronously in the main appdomain:");
       var t1 = Task.Run(() => { DataRetriever d = new DataRetriever();
                                 return d.GetFormattedNumber(formatString);
                               });
       Console.WriteLine(t1.Result);
       Console.WriteLine();

       Console.WriteLine("Executing a task synchronously in two appdomains:");
       var t2 = Task.Run(() => { Console.WriteLine("Thread {0} is running in app domain '{1}'",
                                                   Thread.CurrentThread.ManagedThreadId,
                                                   AppDomain.CurrentDomain.FriendlyName);
                                 AppDomain domain = AppDomain.CreateDomain("Domain2");
                                 DataRetriever d = (DataRetriever) domain.CreateInstanceAndUnwrap(typeof(Example).Assembly.FullName,
                                                   "DataRetriever");
                                 return d.GetFormattedNumber(formatString);
                               });
       Console.WriteLine(t2.Result);
   }
}

public class DataRetriever : MarshalByRefObject
{
   public string GetFormattedNumber(String format)
   {
      Thread thread = Thread.CurrentThread;
      Console.WriteLine("Current culture is {0}", thread.CurrentCulture);
      Console.WriteLine("Thread {0} is running in app domain '{1}'",
                        thread.ManagedThreadId,
                        AppDomain.CurrentDomain.FriendlyName);
      Random rnd = new Random();
      Double value = rnd.NextDouble() * 1000;
      return value.ToString(format);
   }
}
// The example displays output like the following:
//     The example is running on thread 1
//     The current culture is en-US
//     Changed the current culture to fr-FR.
//
//     Executing a task asynchronously in a single appdomain:
//     Current culture is fr-FR
//     Thread 3 is running in app domain 'AsyncCulture4.exe'
//     93,48 €
//
//     Executing a task synchronously in two appdomains:
//     Thread 4 is running in app domain 'AsyncCulture4.exe'
//     Current culture is fr-FR
//     Thread 4 is running in app domain 'Domain2'
//     288,66 €
Imports System.Globalization
Imports System.Runtime.Versioning
Imports System.Threading
Imports System.Threading.Tasks

<Assembly:TargetFramework(".NETFramework,Version=v4.6")>

Module Example
   Public Sub Main()
       Dim formatString As String = "C2"
       Console.WriteLine("The example is running on thread {0}", 
                         Thread.CurrentThread.ManagedThreadId)
       ' Make the current culture different from the system culture.
       Console.WriteLine("The current culture is {0}", 
                         CultureInfo.CurrentCulture.Name)
       If CultureInfo.CurrentCulture.Name = "fr-FR" Then
          Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US")
       Else
          Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR")
       End If

       Console.WriteLine("Changed the current culture to {0}.",
                         CultureInfo.CurrentCulture.Name)
       Console.WriteLine()
       
       ' Call an async delegate to format the values using one format string.
       Console.WriteLine("Executing a task asynchronously in the main appdomain:") 
       Dim t1 = Task.Run(Function()
                            Dim d As New DataRetriever()
                            Return d.GetFormattedNumber(formatString)
                         End Function)
       Console.WriteLine(t1.Result)
       Console.WriteLine() 
       
       Console.WriteLine("Executing a task synchronously in two appdomains:")
       Dim t2 = Task.Run(Function()
                            Console.WriteLine("Thread {0} is running in app domain '{1}'", 
                                              Thread.CurrentThread.ManagedThreadId, 
                                              AppDomain.CurrentDomain.FriendlyName)
                            Dim domain As AppDomain = AppDomain.CreateDomain("Domain2")
                            Dim d As DataRetriever = CType(domain.CreateInstanceAndUnwrap(GetType(Example).Assembly.FullName,
                                                                                          "DataRetriever"), DataRetriever)
                            Return d.GetFormattedNumber(formatString) 
                         End Function) 
       Console.WriteLine(t2.Result)
   End Sub
End Module

Public Class DataRetriever : Inherits MarshalByRefObject
   Public Function GetFormattedNumber(format As String) As String
      Dim thread As Thread = Thread.CurrentThread
      Console.WriteLine("Current culture is {0}", thread.CurrentCulture)
      Console.WriteLine("Thread {0} is running in app domain '{1}'", 
                        thread.ManagedThreadId, 
                        AppDomain.CurrentDomain.FriendlyName)
      Dim rnd As New Random()
      Dim value As Double = rnd.NextDouble() * 1000
      Return value.ToString(format)
   End Function
End Class
' The example displays output like the following:
'     The example is running on thread 1
'     The current culture is en-US
'     Changed the current culture to fr-FR.
'     
'     Executing a task asynchronously in a single appdomain:
'     Current culture is fr-FR
'     Thread 3 is running in app domain 'AsyncCulture4.exe'
'     93,48 €
'     
'     Executing a task synchronously in two appdomains:
'     Thread 4 is running in app domain 'AsyncCulture4.exe'
'     Current culture is fr-FR
'     Thread 4 is running in app domain 'Domain2'
'     288,66 €

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 使用這些覆寫,包括屬性所傳回之實例屬性的使用者設定 DateTimeFormatInfo DateTimeFormat ,以及 NumberFormatInfo 屬性所傳回之實例的屬性 NumberFormat 。 如果使用者設定與與相關聯的文化特性不相容 CultureInfo ,例如,如果選取的行事曆不是的其中一個 OptionalCalendars ,則方法的結果和屬性的值都是未定義的。

替代排序次序

某些文化特性支援一個以上的排序次序。 例如:

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

  • zh-CN (中文 (簡化、PRC) ) 文化特性支援兩種排序次序:依發音 (預設的) 和筆劃計數。 當您具現化 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 電話 Book Sort 0x00010407:
hu-HU 匈牙利文 (匈牙利) 預設值:0x0000040e 技術排序:0x0001040e
ka-GE 喬治亞文 (喬治亞) 傳統:0x00000437 新式排序:0x00010437

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

在通用 Windows 平臺 (UWP) 應用程式中, CurrentCultureCurrentUICulture 屬性為讀寫,就像在 .NET Framework 和 .net Core 應用程式中一樣。 不過,UWP 應用程式會辨識單一文化特性。 CurrentCultureCurrentUICulture 屬性會對應到 Windows 中的第一個值。ApplicationModel。 DefaultCoNtext 語言集合。

在 .NET Framework 和 .net Core 應用程式中,目前的文化特性是每個執行緒的設定,而 CurrentCultureCurrentUICulture 屬性只會反映目前線程的文化特性和 UI 文化特性。 在 UWP 應用程式中,目前的文化特性會對應至Windows。ApplicationModel ,這是全域設定。 DefaultCoNtext 語言集合。 設定 CurrentCultureCurrentUICulture 屬性會變更整個應用程式的文化特性; 文化特性無法針對個別執行緒來設定。

建構函式

CultureInfo(Int32)

根據文化特性識別項所指定的文化特性,初始化 CultureInfo 類別的新執行個體。

CultureInfo(Int32, Boolean)

CultureInfo根據文化特性識別碼所指定的文化特性,以及指定是否要從 Windows 使用使用者選取的文化特性設定的值,初始化類別的新實例。

CultureInfo(String)

根據名稱所指定的文化特性,初始化 CultureInfo 類別的新執行個體。

CultureInfo(String, Boolean)

CultureInfo根據名稱所指定的文化特性,以及指定是否要從 Windows 使用使用者選取的文化特性設定的值,初始化類別的新實例。

屬性

Calendar

取得文化特性使用的預設曆法。

CompareInfo

取得 CompareInfo,定義此文化特性如何比較字串。

CultureTypes

取得和目前 CultureInfo 物件關聯的文化特性類型。

CurrentCulture

取得或設定 CultureInfo 物件,這個物件表示目前線程和以工作為基礎的非同步作業所使用的文化特性。

CurrentUICulture

取得或設定 CultureInfo 物件,此物件代表 Resource Manager 用於執行階段查詢特定文化特性資源的目前使用者介面文化特性。

DateTimeFormat

取得或設定 DateTimeFormatInfo,定義日期和時間在文化特性上適當的顯示格式。

DefaultThreadCurrentCulture

取得或設定目前應用程式定義域中之執行緒的預設文化特性。

DefaultThreadCurrentUICulture

取得或設定目前應用程式定義域中之執行緒的預設 UI 文化特性。

DisplayName

取得完整當地語系化文化特性名稱。

EnglishName

取得以英文格式 為 languagefull [country/regionfull] 格式的文化特性名稱。

IetfLanguageTag

已取代。 取得語言的 RFC 4646 標準識別。

InstalledUICulture

取得 CultureInfo,代表作業系統所安裝的文化特性。

InvariantCulture

取得與文化特性無關的 (不變的) CultureInfo 物件。

IsNeutralCulture

取得值,指出目前 CultureInfo 是否代表中性文化特性。

IsReadOnly

取得值,指出目前 CultureInfo 是否唯讀。

KeyboardLayoutId

取得使用中的輸入地區設定識別項 (Input Locale Identifier)。

LCID

取得目前 CultureInfo 的文化特性識別項。

Name

取得 languagecode2 - country/regioncode2 格式的文化特性名稱。

NativeName

取得文化特性設定為要顯示的文化特性名稱,由語言、國家/地區和選擇性 (Optional) 指令碼組成。

NumberFormat

取得或設定 NumberFormatInfo,定義數字、貨幣和百分比在文化特性上適當的顯示格式。

OptionalCalendars

取得可為文化特性所使用的曆法清單。

Parent

取得 CultureInfo,代表目前 CultureInfo 的父文化特性。

TextInfo

取得 TextInfo,定義與文化特性關聯的書寫系統。

ThreeLetterISOLanguageName

取得目前 CultureInfo 的語言的 ISO 639-2 三個字母代碼。

ThreeLetterWindowsLanguageName

取得 Windows API 中所定義之語言的三個字母代碼。

TwoLetterISOLanguageName

取得目前 CultureInfo 之語言的 ISO 639-1 兩個字母代碼。

UseUserOverride

取得值,指出目前 CultureInfo 是否使用使用者選取的文化特性設定。

方法

ClearCachedData()

重新整理已快取的文化特性相關資訊。

Clone()

建立目前的 CultureInfo 複本。

CreateSpecificCulture(String)

建立 CultureInfo,代表與指定名稱相關的特定文化特性。

Equals(Object)

判斷指定物件是否與目前 CultureInfo 為相同的文化特性。

GetConsoleFallbackUICulture()

在預設的圖形使用者介面 (Graphic User Interface,GUI) 的文化特性不適合主控台應用程式 (Console Application) 時,取得適合的替代使用者介面文化特性。

GetCultureInfo(Int32)

使用指定的文化特性識別項,擷取已快取的唯讀文化特性執行個體。

GetCultureInfo(String)

使用指定的文化特性名稱,擷取已快取的唯讀文化特性執行個體。

GetCultureInfo(String, Boolean)

擷取文化特性的快取、唯讀執行個體。

GetCultureInfo(String, String)

擷取文化特性的快取、唯讀執行個體。 這些參數會指定文化特性,這個文化特性使用另一個文化特性所指定的 TextInfoCompareInfo 物件來初始化。

GetCultureInfoByIetfLanguageTag(String)

已取代。 擷取唯讀的 CultureInfo 物件,其語言特性是透過指定的 RFC 4646 語言標籤所辨識。

GetCultures(CultureTypes)

取得支援的文化特性清單,此清單經過指定的 CultureTypes 參數篩選。

GetFormat(Type)

取得定義如何格式化指定類型的物件。

GetHashCode()

做為目前 CultureInfo 的雜湊函式,適用於雜湊演算法與資料結構,例如雜湊表。

GetType()

取得目前執行個體的 Type

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複製。

(繼承來源 Object)
ReadOnly(CultureInfo)

傳回指定 CultureInfo 物件的唯讀包裝函式。

ToString()

傳回字串,其中包含 CultureInfo languagecode2 - country/regioncode2 格式的目前名稱。

適用於

另請參閱