Поделиться через


Свойство System.Globalization.CultureInfo.InvariantCulture

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

Инвариантная культура является нечувствительной к культуре; она связана с английским языком, но не с конкретной страной или регионом. Вы указываете инвариантный язык и региональные параметры по имени с помощью пустой строки ("") в вызове метода инстанцирования CultureInfo. Это свойство, CultureInfo.InvariantCulture, также извлекает экземпляр инвариантной культуры. Его можно использовать практически в любом методе в пространстве имен System.Globalization, требующем локали. Объекты, возвращаемые такими свойствами, как CompareInfo, DateTimeFormatи NumberFormat, также отражают соглашения о сравнении строк и форматировании инвариантной культуры.

В отличие от данных, зависящих от языка и региональных параметров, которые могут изменяться путем настройки пользователей или обновлений платформы .NET Framework или операционной системы, инвариантные данные языка и региональных параметров стабильны с течением времени и между установленными языками и региональными параметрами и не могут быть настроены пользователями. Это делает инвариантную культуру особенно полезной для операций, требующих результатов, не зависящих от культуры, таких как форматирование и разбор данных, а также для операций сортировки и упорядочивания, требующих представления данных в определенном, устойчивом порядке независимо от культуры.

Строковые операции

Инвариантные языковые и региональные параметры можно использовать для операций со строками, чувствительных к языку и региональным параметрам, которые не зависят от соглашений текущего языка и остаются неизменными в разных культурах. Например, может потребоваться, чтобы отсортированные данные отображались в фиксированном порядке или использовался стандартный набор соглашений по регистру для строк, независимо от текущих настроек культуры. Для этого передайте объект InvariantCulture методу, который имеет параметр CultureInfo, например Compare(String, String, Boolean, CultureInfo) и ToUpper(CultureInfo).

Сохранение данных

Свойство InvariantCulture можно использовать для сохранения данных в формате, независимом от языка и региональных параметров. Это обеспечивает известный формат, который не изменяется и который можно использовать для сериализации и десериализации данных в разных культурах. После десериализации данных его можно отформатировать соответствующим образом на основе культурных соглашений текущего пользователя.

Например, если вы решили сохранить данные даты и времени в строковой форме, можно передать объект InvariantCulture в метод DateTime.ToString(String, IFormatProvider) или DateTimeOffset.ToString(IFormatProvider) для создания строки, и можно передать объект InvariantCulture в метод DateTime.Parse(String, IFormatProvider) или DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles), чтобы преобразовать строку обратно в значение даты и времени. Этот способ гарантирует, что базовые значения даты и времени не изменяются, когда данные считываются или записываются пользователями из разных культур.

В следующем примере используется инвариантная культура для сохранения значения DateTime в виде строки. Затем он анализирует строку и отображает его значение, используя форматы культур Франции и Германии.

using System;
using System.IO;
using System.Globalization;

public class Example
{
   public static void Main()
   {
      // Persist the date and time data.
      StreamWriter sw = new StreamWriter(@".\DateData.dat");

      // Create a DateTime value.
      DateTime dtIn = DateTime.Now;
      // Retrieve a CultureInfo object.
      CultureInfo invC = CultureInfo.InvariantCulture;

      // Convert the date to a string and write it to a file.
      sw.WriteLine(dtIn.ToString("r", invC));
      sw.Close();

      // Restore the date and time data.
      StreamReader sr = new StreamReader(@".\DateData.dat");
      String input;
      while ((input = sr.ReadLine()) != null)
      {
         Console.WriteLine($"Stored data: {input}\n");

         // Parse the stored string.
         DateTime dtOut = DateTime.Parse(input, invC, DateTimeStyles.RoundtripKind);

         // Create a French (France) CultureInfo object.
         CultureInfo frFr = new CultureInfo("fr-FR");
         // Displays the date formatted for the "fr-FR" culture.
         Console.WriteLine($"Date formatted for the {frFr.Name} culture: {dtOut.ToString("f", frFr)}");

         // Creates a German (Germany) CultureInfo object.
         CultureInfo deDe= new CultureInfo("de-De");
         // Displays the date formatted for the "de-DE" culture.
         Console.WriteLine($"Date formatted for {deDe.Name} culture: {dtOut.ToString("f", deDe)}");
      }
      sr.Close();
   }
}
// The example displays the following output:
//    Stored data: Tue, 15 May 2012 16:34:16 GMT
//
//    Date formatted for the fr-FR culture: mardi 15 mai 2012 16:34
//    Date formatted for de-DE culture: Dienstag, 15. Mai 2012 16:34
Imports System.Globalization
Imports System.IO

Module Example
   Public Sub Main()
      ' Persist the date and time data.
      Dim sw As New StreamWriter(".\DateData.dat")
      
      ' Create a DateTime value.      
      Dim dtIn As DateTime = DateTime.Now
      ' Retrieve a CultureInfo object.
      Dim invC As CultureInfo = CultureInfo.InvariantCulture
      
      ' Convert the date to a string and write it to a file.
      sw.WriteLine(dtIn.ToString("r", invC))
      sw.Close()

      ' Restore the date and time data.
      Dim sr As New StreamReader(".\DateData.dat")
      Dim input As String = String.Empty
      Do While sr.Peek() >= 0 
         input = sr.ReadLine()
         Console.WriteLine("Stored data: {0}" , input)    
         Console.WriteLine()
         
         ' Parse the stored string.
         Dim dtOut As DateTime = DateTime.Parse(input, invC, DateTimeStyles.RoundtripKind)

         ' Create a French (France) CultureInfo object.
         Dim frFr As New CultureInfo("fr-FR")
         ' Displays the date formatted for the "fr-FR" culture.
         Console.WriteLine("Date formatted for the {0} culture: {1}" , 
                           frFr.Name, dtOut.ToString("f", frFr))

         ' Creates a German (Germany) CultureInfo object.
         Dim deDe As New CultureInfo("de-De")
         ' Displays the date formatted for the "de-DE" culture.
         Console.WriteLine("Date formatted for {0} culture: {1}" , 
                           deDe.Name, dtOut.ToString("f", deDe))
      Loop
      sr.Close()
   End Sub
End Module
' The example displays the following output:
'    Stored data: Tue, 15 May 2012 16:34:16 GMT
'    
'    Date formatted for the fr-FR culture: mardi 15 mai 2012 16:34
'    Date formatted for de-DE culture: Dienstag, 15. Mai 2012 16:34

Решения по безопасности

Если вы принимаете решение о безопасности (например, разрешить ли доступ к системному ресурсу) на основе результата сравнения строк или изменения регистра, не следует использовать инвариантную культуру. Вместо этого следует выполнять чувствительное или нечувствительное к регистру сравнение, вызывая метод, включающий параметр StringComparison, и передавая StringComparison.Ordinal или StringComparison.OrdinalIgnoreCase в качестве аргумента. Код, выполняющий операции со строками с учетом языка и региональных параметров, может вызвать уязвимости системы безопасности, если текущий язык и региональные параметры изменены или если язык и региональные параметры на компьютере, на котором выполняется код, отличается от языка и региональных параметров, используемых для тестирования кода. Напротив, порядковое сравнение зависит исключительно от двоичного значения сравниваемых символов.