CultureInfo 类

定义

提供有关特定区域性(对于非托管代码开发,则称为“区域设置”)的信息。 这些信息包括区域性的名称、书写系统、使用的日历、字符串的排序顺序以及对日期和数字的格式化设置。

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 类提供特定于区域性的信息,例如语言、子语言、国家/地区、日历和与特定区域性关联的约定。 此类还提供对特定于区域性的DateTimeFormatInfoNumberFormatInfoCompareInfoTextInfo实例和对象的访问。 这些对象包含区域性特定操作所需的信息,例如大小写、格式设置日期和数字以及比较字符串。 此类 CultureInfo 由格式化、分析或操作特定于区域性的数据(例如 StringDateTime、) DateTimeOffset和数值类型的类直接或间接使用。

本节内容:

区域性名称和标识符
固定、中立和特定区域性
自定义区域性
动态区域性数据
CultureInfo 和文化数据
当前区域性和当前 UI 区域性
获取所有区域性
区域性和线程
区域性和应用程序域
区域性和基于任务的异步操作
CultureInfo 对象序列化
控制面板替代
备用排序顺序
区域性和Windows应用\

区域性名称和标识符

CultureInfo 类根据 RFC 4646 为每个区域性指定唯一名称。 该名称是与语言关联的 ISO 639 双字母小写区域性代码和与国家或地区关联的 ISO 3166 双字母大写子区域性代码的组合。 此外,对于面向 .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**country/regioncode2-scripttag-。 这种类型的文化名称的一个示例是 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版本或服务包可以更改可用区域性。 应用程序可以使用该类添加自定义区域性 CultureAndRegionInfoBuilder 。 用户可以使用 Microsoft Locale Builder 工具添加自己的自定义区域性。 Microsoft Locale Builder 使用 CultureAndRegionInfoBuilder 类以托管代码编写。

多个非重复名称与区域性密切相关,尤其是与以下类成员关联的名称:

固定区域性、非特定区域性和特定区域性

区域性通常分为三组:固定区域性、中性文化和特定区域性。

固定区域性不区分区域性。 应用程序使用空字符串 (“”) 或其标识符按名称指定固定区域性。 InvariantCulture 定义固定区域性的实例。 它与英语相关联,但不与任何国家/地区相关联。 它几乎用于需要区域性的命名空间中的任何 Globalization 方法。

中性文化是一种与语言关联的区域性,但与国家/地区无关。 特定区域性是与语言和国家/地区关联的区域性。 例如, fr 是法国文化的中性名称,是 fr-FR 特定法语 (法国) 文化的名称。 请注意,中文 (简体) 和中国 (传统) 也被视为中性文化。

不建议为中性区域性创建类的 CompareInfo 实例,因为它包含的数据是任意的。 若要显示和排序数据,请同时指定语言和区域。 此外, Name 为中性区域性创建的对象的属性 CompareInfo 仅返回国家/地区,不包括该区域。

定义的区域性具有层次结构,其中特定区域性的父区域性是中性区域性,而中性区域性的父区域性是固定区域性。 该 Parent 属性包含与特定区域性关联的中性区域性。 自定义区域性应定义 Parent 符合此模式的属性。

如果特定区域性的资源在操作系统中不可用,则使用关联的中性区域性的资源。 如果中性区域性的资源不可用,则使用主程序集中嵌入的资源。 有关资源回退过程的详细信息,请参阅 打包和部署资源

Windows API 中的区域设置列表与 .NET 支持的区域性列表略有不同。 例如,如果需要与Windows的互操作性(例如通过 p/invoke 机制),则应用程序应使用为操作系统定义的特定区域性。 使用特定区域性可确保与等效Windows区域设置保持一致,该区域设置使用与区域设置标识符相同的LCID区域设置标识。

只能为固定区域性或特定区域性创建 A DateTimeFormatInfo 或 a NumberFormatInfo ,而不是针对中性区域性创建。

TaiwanCalendar Thread.CurrentCulture如果是DateTimeFormatInfo.Calendar但未设置为 zh-TW,则DateTimeFormatInfo.GetEraNameDateTimeFormatInfo.NativeCalendarName返回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-TW”是“zh-Hant-TW”文化的别名。 别名区域性不是通过调用GetCultures方法返回的,并且可能具有不同于其Windows对应区域性的不同属性值,包括不同的Parent区域性。 zh-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。 此行为还适用于调用 Equals “zh-TW” CultureInfo 实例并将其传递给“zh-Hant-Tw”实例。

动态区域性数据

除固定区域性外,区域性数据是动态的。 即使对于预定义区域性也是如此。 例如,国家或地区采用新货币、更改字词的拼写或更改其首选日历,以及区域性定义更改以跟踪此问题。 自定义区域性可能未经通知更改,任何特定区域性都可能被自定义替换区域性覆盖。 此外,如下面所述,单个用户可以替代文化首选项。 应用程序应始终在运行时获取区域性数据。

注意

保存数据时,应用程序应使用固定区域性、二进制格式或与区域性无关的特定格式。 根据与特定区域性(非固定区域性)关联的当前值保存的数据可能会变得不可读,或者如果区域性发生更改,则表示含义可能会发生变化。

当前区域性和当前 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化反映用户替代的对象。 构造CultureInfo(String, Boolean)函数允许指定新实例CultureInfo化对象是否反映用户替代(如果新区域性与当前Windows区域性相同)。

  2. CultureInfo对象分配给 CultureInfo.CurrentCulture .NET Core 上的 or CultureInfo.CurrentUICulture 属性,.NET Framework 4.6 及更高版本。 (在 .NET Framework 4.5.2 及更早版本中,可以将对象Thread.CurrentCulture分配给 CultureInfo or Thread.CurrentUICulture property.)

以下示例检索当前区域性。 如果它除了法国 (法国) 文化之外,它把目前的文化更改为法国 (法国) 。 否则,它将当前文化更改为法国 (卢森堡) 。

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 €

可以通过调用 ThreadPool.QueueUserWorkItem(WaitCallback, Object) 该方法,以类似的方式设置线程池线程的区域性和 UI 区域性。

从 .NET Framework 4.5 开始,可以通过向和属性分配CultureInfo表示该区域性的对象来更直接地设置应用程序域中所有线程的区域性和 DefaultThreadCurrentUICulture UI 区域性DefaultThreadCurrentCulture。 以下示例使用这些属性来确保默认应用程序域中的所有线程共享同一区域性。

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 €

警告

DefaultThreadCurrentCulture尽管这些属性DefaultThreadCurrentUICulture是静态成员,但它们仅为设置这些属性值时当前的应用程序域定义默认区域性和默认 UI 区域性。 有关详细信息,请参阅下一部分: 区域性和应用程序域

向属性DefaultThreadCurrentUICulture分配值DefaultThreadCurrentCulture时,如果线程未显式分配区域性,则应用程序域中线程的区域性和 UI 区域性也会更改。 但是,这些线程仅在当前应用程序域中执行时反映新的区域性设置。 如果这些线程在另一个应用程序域中执行,则其区域性将成为为该应用程序域定义的默认区域性。 因此,我们建议始终设置主应用程序线程的区域性,而不依赖于 DefaultThreadCurrentCulture 属性 DefaultThreadCurrentUICulture 来更改它。

区域性和应用程序域

DefaultThreadCurrentCulture 并且 DefaultThreadCurrentUICulture 是静态属性,仅针对设置或检索属性值时当前的应用程序域定义默认区域性。 以下示例将默认应用程序域中的默认区域性和默认 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

有关区域性和应用程序域的详细信息,请参阅 应用程序域 主题中的“应用程序域和线程”部分。

区域性和基于任务的异步操作

基于任务的异步编程模式使用TaskTask<TResult>对象在线程池线程上异步执行委托。 特定任务运行的特定线程事先未知,但仅在运行时确定。

对于面向 .NET Framework 4.6 或更高版本的应用,区域性是异步操作上下文的一部分。 换句话说,从面向 .NET Framework 4.6 的应用开始,异步操作默认继承启动线程的值CurrentCultureCurrentUICulture属性。 如果当前区域性或当前 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 €

DefaultThreadCurrentCulture 并且 DefaultThreadCurrentUICulture 是每应用域属性;也就是说,它们为所有未在特定应用程序域中显式分配区域性的所有线程建立默认区域性。 但是,对于面向 .NET Framework 4.6 或更高版本的应用,即使任务跨越应用域边界,调用线程的区域性仍保留在异步任务的上下文的一部分。

下面的示例演示调用线程的区域性仍然是基于任务的异步操作的当前区域性,即使任务正在执行的方法跨越应用程序域边界也是如此。 它定义一个类, DataRetriever使用单个方法, GetFormattedNumber该类返回格式为货币值的 1 到 1,000 之间的随机双精度浮点数。 运行第一个任务,只需实例化 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 成功反序列化。 以下三个示例演示了为什么这种情况并不总是如此:

  • If the CultureTypes property value is CultureTypes.InstalledWin32Cultures, and if that culture was first introduced in a particular version of the Windows operating system, it is not possible to deserialize it on an earlier version of Windows. 例如,如果在Windows 10中引入区域性,则无法在Windows 8上反序列化区域性。

  • CultureTypes如果值为CultureTypes.UserCustomCulture,并且反序列化的计算机未安装此用户自定义区域性,则无法反序列化它。

  • CultureTypes如果值为CultureTypes.ReplacementCultures,并且反序列化的计算机没有此替换区域性,则它将反序列化为同一名称,但不是所有相同的特征。 例如,如果是 en-US 计算机 A 上的替换区域性,但不是在计算机 B 上,如果 CultureInfo 引用此区域性的对象在计算机 A 上序列化,并在计算机 B 上反序列化,则不会传输区域性的任何自定义特征。 区域性已成功反序列化,但含义不同。

控制面板替代

用户可以选择通过控制面板的区域和语言选项部分替代与当前区域性Windows关联的某些值。 例如,用户可以选择以不同的格式显示日期,或使用区域性的默认值以外的货币。 通常,应用程序应遵循这些用户替代。

如果UseUserOverride指定true区域性与当前Windows区域性匹配,则CultureInfo使用这些替代,包括属性返回DateTimeFormat的实例的属性的用户设置,以及属性返回的NumberFormat实例的属性DateTimeFormatInfoNumberFormatInfo。 如果用户设置与关联的 CultureInfo区域性不兼容,例如,如果所选日历不是其中一个 OptionalCalendars,则方法的结果和属性的值未定义。

备用排序顺序

某些区域性支持多个排序顺序。 例如:

  • 西班牙 (西班牙) 文化有两种排序顺序:默认的国际排序顺序和传统的排序顺序。 实例化 CultureInfo 具有 es-ES 区域性名称的对象时,将使用国际排序顺序。 实例化 CultureInfo 具有 es-ES-tradnl 区域性名称的对象时,将使用传统的排序顺序。

  • (zh-CN 中文 (简体中文,中国) ) 区域性支持两种排序顺序:按发音 (默认) 和笔划计数。 实例化 CultureInfo 具有 zh-CN 区域性名称的对象时,将使用默认排序顺序。 实例化 CultureInfo 具有本地标识符0x00020804的对象时,字符串按笔划计数进行排序。

下表列出了支持备用排序顺序的区域性以及默认排序顺序和备用排序顺序的标识符。

区域性名称 环境 默认排序名称和标识符 备用排序名称和标识符
es-ES 西班牙语(西班牙) 国际:0x00000C0A 传统:0x0000040A
zh-TW 中文(台湾) 笔划计数:0x00000404 Bopomofo: 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) 应用中,CurrentCulture这些应用和CurrentUICulture属性是读写的,就像在 .NET Framework 和 .NET Core 应用中一样。 但是,UWP 应用可识别单个区域性。 属性CurrentCultureCurrentUICulture映射到Windows中的第一个值。ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages 集合。

在 .NET Framework 和 .NET Core 应用中,当前区域性是按线程设置,并且CurrentCultureCurrentUICulture属性仅反映当前线程的区域性和 UI 区域性。 在 UWP 应用中,当前区域性映射到Windows。ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages 集合,这是一个全局设置。 CurrentCulture设置或CurrentUICulture属性可更改整个应用的区域性;区域性不能按线程设置。

构造函数

CultureInfo(Int32)

根据区域性标识符指定的区域性初始化 CultureInfo 类的新实例。

CultureInfo(Int32, Boolean)

基于区域性标识符指定的区域性以及指定是否使用用户所选区域性设置的值初始化类的新实例CultureInfoWindows。

CultureInfo(String)

根据由名称指定的区域性初始化 CultureInfo 类的新实例。

CultureInfo(String, Boolean)

根据名称指定的区域性和指定值初始化类的新实例CultureInfo,该值指定是否使用用户选择的区域性设置Windows。

属性

Calendar

获取区域性使用的默认日历。

CompareInfo

获取为区域性定义如何比较字符串的 CompareInfo

CultureTypes

获取属于当前 CultureInfo 对象的区域性类型。

CurrentCulture

获取或设置 CultureInfo 表示当前线程和基于任务的异步操作使用的区域性的对象。

CurrentUICulture

获取或设置 CultureInfo 对象,该对象表示资源管理器在运行时查找区域性特定资源时所用的当前用户接口区域性。

DateTimeFormat

获取或设置 DateTimeFormatInfo,它定义适合区域性的、显示日期和时间的格式。

DefaultThreadCurrentCulture

获取或设置当前应用程序域中线程的默认区域性。

DefaultThreadCurrentUICulture

获取或设置当前应用程序域中线程的默认 UI 区域性。

DisplayName

获取完整的本地化区域性名称。

EnglishName

获取格式为 languagefull [country/regionfull] 的英语区域性名称。

IetfLanguageTag

已弃用。 获取某种语言的 RFC 4646 标准标识。

InstalledUICulture

获取表示操作系统中安装的区域性的 CultureInfo

InvariantCulture

获取不依赖于区域性(固定)的 CultureInfo 对象。

IsNeutralCulture

获取一个值,该值指示当前 CultureInfo 是否表示非特定区域性。

IsReadOnly

获取一个值,该值指示当前 CultureInfo 是否为只读。

KeyboardLayoutId

获取活动的输入区域设置标识符。

LCID

获取当前 CultureInfo 的区域性标识符。

Name

获取格式为 languagecode2-country/regioncode2 的区域性名称。

NativeName

获取为区域性设置的显示名称,它由语言、国家/地区以及可选脚本组成。

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()

如果默认的图形用户界面区域性不合适,则获取适合控制台应用程序的备用用户界面区域性。

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。

适用于

另请参阅