Свойство System.Globalization.CultureInfo.CurrentCulture
В этой статье приводятся дополнительные замечания к справочной документации по этому API.
Объект CultureInfo, возвращаемый свойством CurrentCulture вместе со связанными объектами, определяет формат по умолчанию для дат, времени, чисел и валют, порядок сортировки текста, правила использования регистра и сравнения строк.
Текущая культура — это свойство выполняемого потока. При установке этого свойства объекту CultureInfo, представляющему новую культуру, значение свойства Thread.CurrentThread.CurrentCulture
также изменяется. Однако мы рекомендуем всегда использовать свойство CultureInfo.CurrentCulture для получения и задания текущей культуры.
Объект, возвращаемый CultureInfo
этим свойством, доступен только для чтения. Это означает, что вы не можете изменить существующий объект, например, изменив объект DateTimeFormat
. Чтобы изменить формат даты и времени или другой аспект текущих языковых и региональных параметров, создайте новый CultureInfo
объект и присвойте его свойству.
Как определяется культура потока
При запуске потока его культура изначально определяется следующим образом:
Извлекая культуру, указанную свойством DefaultThreadCurrentCulture в домене приложения, в котором выполняется поток, если значение свойства не
null
.Если поток является потоком пула потоков, выполняющим асинхронную операцию на основе задачи, его культура определяется культурой вызывающего потока. В следующем примере изменяется текущая культура на португальскую (Бразилия) и запускается шесть задач, каждая из которых отображает идентификатор потока, идентификатор задачи и её текущую культуру. Каждая из задач (и потоков) наследовали культуру вызывающего потока.
using System; using System.Collections.Generic; using System.Globalization; using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; public class Example14 { public static async Task Main() { var tasks = new List<Task>(); Console.WriteLine($"The current culture is {Thread.CurrentThread.CurrentCulture.Name}"); Thread.CurrentThread.CurrentCulture = new CultureInfo("pt-BR"); // Change the current culture to Portuguese (Brazil). Console.WriteLine($"Current culture changed to {Thread.CurrentThread.CurrentCulture.Name}"); Console.WriteLine($"Application thread is thread {Thread.CurrentThread.ManagedThreadId}"); // Launch six tasks and display their current culture. for (int ctr = 0; ctr <= 5; ctr++) tasks.Add(Task.Run(() => { Console.WriteLine($"Culture of task {Task.CurrentId} on thread {Thread.CurrentThread.ManagedThreadId} is {Thread.CurrentThread.CurrentCulture.Name}"); })); await Task.WhenAll(tasks.ToArray()); } } // The example displays output like the following: // The current culture is en-US // Current culture changed to pt-BR // Application thread is thread 9 // Culture of task 2 on thread 11 is pt-BR // Culture of task 1 on thread 10 is pt-BR // Culture of task 3 on thread 11 is pt-BR // Culture of task 5 on thread 11 is pt-BR // Culture of task 6 on thread 11 is pt-BR // Culture of task 4 on thread 10 is pt-BR
Imports System.Globalization Imports System.Threading Module Example1 Public Sub S1() Dim tasks As New List(Of Task) Console.WriteLine("The current culture is {0}", Thread.CurrentThread.CurrentCulture.Name) Thread.CurrentThread.CurrentCulture = New CultureInfo("pt-BR") ' Change the current culture to Portuguese (Brazil). Console.WriteLine("Current culture changed to {0}", Thread.CurrentThread.CurrentCulture.Name) Console.WriteLine("Application thread is thread {0}", Thread.CurrentThread.ManagedThreadId) ' Launch six tasks and display their current culture. For ctr As Integer = 0 To 5 tasks.Add(Task.Run(Sub() Console.WriteLine("Culture of task {0} on thread {1} is {2}", Task.CurrentId, Thread.CurrentThread.ManagedThreadId, Thread.CurrentThread.CurrentCulture.Name) End Sub)) Next Task.WaitAll(tasks.ToArray()) End Sub End Module ' The example displays output like the following: ' The current culture is en-US ' Current culture changed to pt-BR ' Application thread is thread 9 ' Culture of task 2 on thread 11 is pt-BR ' Culture of task 1 on thread 10 is pt-BR ' Culture of task 3 on thread 11 is pt-BR ' Culture of task 5 on thread 11 is pt-BR ' Culture of task 6 on thread 11 is pt-BR ' Culture of task 4 on thread 10 is pt-BR
Дополнительные сведения см. в разделе "Культура и асинхронные операции на основе заданий".
Вызывая функцию
GetUserDefaultLocaleName
в Windows или функциюuloc_getDefault
из ICU на системах, таких как Unix, которая в настоящее время вызывает функцию POSIXsetlocale
с категориейLC_MESSAGES
,
Обратите внимание, что если задать определенный язык и региональные параметры, отличные от установленного системой языка и региональных параметров или предпочитаемого пользователем языка и региональных параметров, а приложение запускает несколько потоков, текущий язык и региональные параметры этих потоков будут языком и региональными параметрами, возвращаемыми GetUserDefaultLocaleName
функцией, если только вы не назначите DefaultThreadCurrentCulture свойству в домене приложения, в котором выполняется поток.
Дополнительные сведения о том, как определяется культура потока, см. в разделе "Культура и потоки" на справочной странице CultureInfo.
Получение текущей культуры
Свойство CultureInfo.CurrentCulture является настройкой для каждого потока; то есть, каждый поток может иметь свою собственную культуру. Вы получаете культуру текущего CultureInfo.CurrentCulture потока, извлекая значение свойства, как показано в следующем примере.
using System;
using System.Globalization;
public class Example5
{
public static void Main()
{
CultureInfo culture = CultureInfo.CurrentCulture;
Console.WriteLine($"The current culture is {culture.NativeName} [{culture.Name}]");
}
}
// The example displays output like the following:
// The current culture is English (United States) [en-US]
Imports System.Globalization
Module Example3
Public Sub S1()
Dim culture As CultureInfo = CultureInfo.CurrentCulture
Console.WriteLine("The current culture is {0} [{1}]",
culture.NativeName, culture.Name)
End Sub
End Module
' The example displays output like the following:
' The current culture is English (United States) [en-US]
Явно задать свойство CurrentCulture
Чтобы изменить используемые существующим потоком язык и региональные параметры, задайте свойству CultureInfo.CurrentCulture новое значение языка и региональных параметров. Если вы явно изменяете язык и региональные настройки потока таким образом, то это изменение сохраняется даже при пересечении потоком границ области приложения. В следующем примере текущая культура потока изменяется на нидерландскую (Нидерланды). Также показано, что, когда текущий поток пересекает границы домена приложения, его текущая культура остаётся изменённой.
using System;
using System.Globalization;
using System.Threading;
public class Info11 : MarshalByRefObject
{
public void ShowCurrentCulture()
{
Console.WriteLine($"Culture of {Thread.CurrentThread.Name} in application domain {AppDomain.CurrentDomain.FriendlyName}: {CultureInfo.CurrentCulture.Name}");
}
}
public class Example11
{
public static void Main()
{
Info11 inf = new Info11();
// Set the current culture to Dutch (Netherlands).
Thread.CurrentThread.Name = "MainThread";
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("nl-NL");
inf.ShowCurrentCulture();
// Create a new application domain.
AppDomain ad = AppDomain.CreateDomain("Domain2");
Info11 inf2 = (Info11)ad.CreateInstanceAndUnwrap(typeof(Info11).Assembly.FullName, "Info11");
inf2.ShowCurrentCulture();
}
}
// The example displays the following output:
// Culture of MainThread in application domain ChangeCulture1.exe: nl-NL
// Culture of MainThread in application domain Domain2: nl-NL
Imports System.Globalization
Imports System.Threading
Public Class Info : Inherits MarshalByRefObject
Public Sub ShowCurrentCulture()
Console.WriteLine("Culture of {0} in application domain {1}: {2}",
Thread.CurrentThread.Name,
AppDomain.CurrentDomain.FriendlyName,
CultureInfo.CurrentCulture.Name)
End Sub
End Class
Module Example2
Public Sub S1()
Dim inf As New Info()
' Set the current culture to Dutch (Netherlands).
Thread.CurrentThread.Name = "MainThread"
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture("nl-NL")
inf.ShowCurrentCulture()
' Create a new application domain.
Dim ad As AppDomain = AppDomain.CreateDomain("Domain2")
Dim inf2 As Info = CType(ad.CreateInstanceAndUnwrap(GetType(Info).Assembly.FullName, "Info"),
Info)
inf2.ShowCurrentCulture()
End Sub
End Module
' This example displays the following output:
' Culture of MainThread in application domain Example.exe: nl-NL
' Culture of MainThread in application domain Domain2: nl-NL
Примечание.
Для изменения культуры с помощью свойства CultureInfo.CurrentCulture требуется разрешение SecurityPermission с установленным значением ControlThread. Манипулирование потоками опасно из-за состояния безопасности, связанного с потоками. Таким образом, это разрешение должно быть предоставлено только надежному коду, а затем только по мере необходимости. Невозможно изменить культуру потока в полунадежном коде.
Начиная с .NET Framework 4, вы можете явно изменить текущую культуру потока на определённую культуру (например, французский (Канада)) или нейтральную культуру (например, французский). CultureInfo Когда объект представляет нейтральную культуру, значения свойств, таких как CultureInfo, Calendar, CompareInfo, DateTimeFormat, NumberFormat и TextInfo, отражают конкретную культуру, связанную с нейтральной культурой. Например, доминирующая культура для английского нейтрального языка — английский (США); доминирующей культурой для немецкой культуры является немецкий (Германия). В следующем примере продемонстрировано различие в форматировании, когда текущая культура установлена на конкретную культуру, французская (Канада), и на нейтральную культуру, французская.
using System;
using System.Globalization;
using System.Threading;
public class Example12
{
public static void Main()
{
double value = 1634.92;
CultureInfo.CurrentCulture = new CultureInfo("fr-CA");
Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"{value:C2}\n");
Thread.CurrentThread.CurrentCulture = new CultureInfo("fr");
Console.WriteLine($"Current Culture: {CultureInfo.CurrentCulture.Name}");
Console.WriteLine($"{value:C2}");
}
}
// The example displays the following output:
// Current Culture: fr-CA
// 1 634,92 $
//
// Current Culture: fr
// 1 634,92 €
Imports System.Globalization
Imports System.Threading
Module Example4
Public Sub S1()
Dim value As Double = 1634.92
CultureInfo.CurrentCulture = New CultureInfo("fr-CA")
Console.WriteLine("Current Culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("{0:C2}", value)
Console.WriteLine()
Thread.CurrentThread.CurrentCulture = New CultureInfo("fr")
Console.WriteLine("Current Culture: {0}",
CultureInfo.CurrentCulture.Name)
Console.WriteLine("{0:C2}", value)
End Sub
End Module
' The example displays the following output:
' Current Culture: fr-CA
' 1 634,92 $
'
' Current Culture: fr
' 1 634,92 €
Вы также можете использовать свойство CultureInfo.CurrentCulture вместе со свойством HttpRequest.UserLanguages для задания свойства CurrentCulture приложения ASP.NET в соответствии с предпочитаемой культурой пользователя, как показано в следующем примере.
CultureInfo.CurrentCulture = CultureInfo.CreateSpecificCulture(Request13.UserLanguages[0]);
Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(Request.UserLanguages(0))
Текущие региональные параметры и пользовательские переопределения
Windows позволяет пользователям переопределить стандартные значения CultureInfo свойств объекта и связанных с ним объектов с помощью региональных и языковых параметров на панели управления. Объект CultureInfo, возвращаемый свойством CurrentCulture, отражает пользовательские переопределения в следующих случаях:
Если языковые и региональные параметры текущего потока задаются неявно с помощью функции Windows
GetUserDefaultLocaleName
.Если текущий язык и региональные параметры потока, определенные DefaultThreadCurrentCulture свойством, соответствуют текущему языку и региональных параметров системы Windows.
Если текущие региональные настройки потока явно заданы культурам, возвращаемым методом CreateSpecificCulture, и эти настройки соответствуют текущей культуре системы Windows.
Если текущий язык и региональные параметры потока заданы явным образом в качестве экземпляра языка и региональных параметров, созданных CultureInfo(String) конструктором, и этот язык и региональные параметры соответствуют текущему языку и региональных параметров системы Windows.
В некоторых случаях, особенно для серверных приложений, установка текущей культуры на объект CultureInfo, который отражает переопределения пользователей, может оказаться нежелательной. Вместо этого можно задать текущее языковое окружение в объекте CultureInfo, который не учитывает пользовательские переопределения следующими способами:
Вызывая конструктор CultureInfo(String, Boolean) со значением
false
для аргументаuseUserOverride
.При вызове метода GetCultureInfo, который возвращает кэшированный объект CultureInfo, доступный только для чтения.
Текущая культура и приложения UWP
В приложениях универсальной платформы Windows (UWP) свойство CurrentCulture является одновременно доступным для чтения и записи, как и в приложениях .NET Framework и .NET Core. его можно использовать как для получения, так и для задания текущей культуры. Однако приложения UWP не различают текущую культуру и текущую культуру пользовательского интерфейса. Свойства CurrentCulture и CurrentUICulture соответствуют первому значению в коллекции Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages.
В приложениях .NET Framework и .NET Core текущая культура является настройкой для каждого потока, и свойство CurrentCulture отражает культуру только текущего потока. В приложениях UWP текущая культура сопоставляется со свойством Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages, которое является глобальным параметром. Настройка свойства CurrentCulture изменяет культуру всего приложения; Культуру нельзя задать в рамках потока.