Свойство 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 {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 (int ctr = 0; ctr <= 5; ctr++)
                tasks.Add(Task.Run(() =>
                {
                    Console.WriteLine("Culture of task {0} on thread {1} is {2}",
                                      Task.CurrentId,
                                      Thread.CurrentThread.ManagedThreadId,
                                      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, которая в настоящее время вызывает функцию POSIX setlocale с категорией LC_MESSAGESв системах, таких как Unix.

Обратите внимание, что если задать определенный язык и региональные параметры, отличные от установленного системой языка и региональных параметров или предпочитаемого пользователем языка и региональных параметров, а приложение запускает несколько потоков, текущий язык и региональные параметры этих потоков будут языком и региональными параметрами, возвращаемыми 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 {0} [{1}]",
                        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 {0} in application domain {1}: {2}",
                          Thread.CurrentThread.Name,
                          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, DateTimeFormatNumberFormatи 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: {0}",
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("{0:C2}\n", value);

      Thread.CurrentThread.CurrentCulture = new CultureInfo("fr");
      Console.WriteLine("Current Culture: {0}",
                        CultureInfo.CurrentCulture.Name);
      Console.WriteLine("{0:C2}", value);
   }
}
// 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) конструктор со значением аргумента falseuseUserOverride .

  • Вызывая GetCultureInfo метод, который возвращает кэшированный объект только для CultureInfo чтения.

Текущие региональные параметры и приложения UWP

В приложениях универсальная платформа Windows (UWP) свойство выполняется чтение и запись, CurrentCulture так же как и в приложениях платформа .NET Framework и .NET Core. Его можно использовать как для получения, так и для задания текущего языка и региональных параметров. Однако приложения UWP не различают текущий язык и региональные параметры и текущие региональные параметры пользовательского интерфейса. Свойства CurrentCulture сопоставляют первое значение в коллекции Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages.CurrentUICulture

В приложениях платформа .NET Framework и .NET Core текущий язык и региональные параметры — это параметр для каждого потока, а CurrentCulture свойство отражает только язык и региональные параметры текущего потока. В приложениях UWP текущий язык и региональные параметры сопоставляется со свойством Windows.ApplicationModel.Resources.Core.ResourceManager.DefaultContext.Languages , которое является глобальным параметром. CurrentCulture Настройка свойства изменяет язык и региональные параметры всего приложения. Язык и региональные параметры нельзя задать на основе потока.