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

本节内容:

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

区域性名称和标识符

CultureInfo 根据 RFC 4646 指定每个区域性的唯一名称。 该名称与与语言关联的 ISO 639 双字母小写区域性代码与与国家/地区关联的 ISO 3166 双字母大写子区域性代码的组合。 此外,对于面向 .NET Framework 4 或更高版本且在 Windows 10 或更高版本下运行的应用,支持对应于有效 BCP-47 语言标记的区域性名称。

备注

将区域性名称传递给类构造函数或 方法(如 CreateSpecificCulture 或 )时 CultureInfo ,其大小写没有意义。

基于 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 Uzbek (西里尔文、) 。 在 Windows Vista 之前Windows操作系统上,包含脚本的区域性名称使用 模式,例如,对于 languagecode2 - country/regioncode2 - scripttag uz-UZ-Cyrl Uzbek (西里尔文、) 。

非特定区域性仅由双字母小写语言代码指定。 例如, fr 指定法语的非特定区域性,并 de 指定德语的非特定区域性。

备注

有两个区域性名称与此规则冲突。 简体中文 (、) )和繁体中文 zh-Hans (() )是 zh-Hant 非特定区域性。 区域性名称表示当前标准,除非有使用旧名称和 的原因,否则应 zh-CHS 使用该名称 zh-CHT

区域性标识符是标准的国际数字缩写,具有唯一标识已安装区域性之一所需的组件。 应用程序可以使用预定义的区域性标识符或定义自定义标识符。

命名空间中的此 类和其他类使用某些预定义的区域性名称和 System.Globalization 标识符。 有关系统的详细区域性Windows,请参阅语言支持的语言/区域名称列表中的语言标记Windows。 列名遵循 BCP 47 定义的标准。

区域性名称和标识符只表示特定计算机上可找到的区域性子集。 Windows版本或 Service Pack 可以更改可用区域性。 应用程序可以使用 类添加自定义 CultureAndRegionInfoBuilder 区域性。 用户可以使用 Microsoft 区域设置生成器工具 添加自己的自定义 区域性。 Microsoft 区域设置生成器是使用 类以托管代码 CultureAndRegionInfoBuilder 编写的。

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

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

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

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

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

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

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

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

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

只能 DateTimeFormatInfo 为固定区域性或特定区域性创建 或 , NumberFormatInfo 不能为非特定区域性创建 。

如果 DateTimeFormatInfo.CalendarTaiwanCalendar ,但 未设置为 ,则 、 和 返回空字符串 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 对象因基础平台的不同而不同。 具体而言,中文 (简体、中国) 和 )或中文 (繁体、台湾) 是 Windows 系统上可用的区域性,但它们是 Unix 系统上的别名 zh-CN zh-TW 区域性。 "zh-CN"是"zh-Hans-CN"区域性的别名,"zh-TW"是"zh-Hant-TW"区域性的别名。 别名区域性不是通过调用 方法返回的,并且可能具有不同的属性值(包括不同的区域性)Windows GetCultures Parent 对应。 对于 zh-CNzh-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 类构造函数并向其传递区域性的名称,来实例化表示该区域性的对象。 CultureInfo(String)构造函数实例化一个 CultureInfo 对象,该对象在新区域性与当前 Windows 区域性相同时反映用户重写。 CultureInfo(String, Boolean)构造函数允许你指定新的实例化 CultureInfo 对象是否反映用户重写(如果新区域性与当前 Windows 区域性相同)。

  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 区域性。 有关详细信息,请参阅下一节 区域性和应用程序域

DefaultThreadCurrentCulture 和属性赋值时 DefaultThreadCurrentUICulture ,如果应用程序域中的线程的区域性和 UI 区域性没有显式分配有区域性,则这些线程的区域性和 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

有关区域性和应用程序域的详细信息,请参阅 应用程序域 主题中的 "应用程序域和线程" 一节。

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

基于任务的异步编程模式使用 TaskTask<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 的应用程序 .NET Framework 4.5 及更高版本,但在 .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 。 以下三个示例说明了为何不总是出现这种情况:

  • 如果属性值为 ,并且该区域性是在 Windows 操作系统的特定版本中首次引入的,则不能对早期版本的 Windows 进行 CultureTypes CultureTypes.InstalledWin32Cultures 反Windows。 例如,如果区域性是在 Windows 10 中引入的,则不能在Windows 8。

  • 如果值为 ,并且其反反化的计算机未安装此用户自定义区域性,则不能反 CultureTypes CultureTypes.UserCustomCulture 其反化。

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

控制面板重写

用户可能会选择重写与当前区域性关联的一些值,Windows区域性和语言选项部分控制面板。 例如,用户可能会选择以其他格式显示日期,或者使用区域性的默认货币。 通常,应用程序应遵守这些用户替代。

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

备用排序顺序

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

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

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

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

区域性名称 环境 默认排序名称和标识符 备用排序名称和标识符
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 电话 0x00010407 Book Sort
hu-HU 匈牙利语(匈牙利) 默认值:0x0000040e 技术排序:0x0001040e
ka-GE 格鲁吉亚语(格鲁吉亚) 传统:0x00000437 新式排序:0x00010437

当前区域性和 UWP 应用

在 Universal Windows Platform (UWP) 应用中, 和 属性是读写的,就像它们在 CurrentCulture CurrentUICulture .NET Framework 和 .NET Core 应用中一样。 但是,UWP 应用可识别单个区域性。 和 CurrentCulture CurrentUICulture 属性映射到属性中的第一Windows。ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages集合。

在 .NET Framework 和 .NET Core 应用中,当前区域性是按线程设置,并且 和 属性仅反映当前线程的区域性 CurrentCulture CurrentUICulture 和 UI 区域性。 在 UWP 应用中,当前区域性映射到Windows。ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages集合,这是一个全局设置。 设置 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 对象,该对象表示资源管理器在运行时查找区域性特定资源时所用的当前用户接口区域性。

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。

适用于

另请参阅