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


Использование свойства InvariantCulture

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

Вопросы безопасности

Если решение, влияющее на безопасность, принимается на основе сравнения строк или изменения регистра, в приложении вместо InvariantCulture следует использовать порядковое сравнение, не учитывающее регистр. Заданные по умолчанию реализации методов String.Compare и String.ToUpper используют свойство CurrentCulture. Код, выполняющий строковые операции, зависящие от языка и региональных параметров, может стать причиной снижения уровня безопасности при изменении CurrentCulture или при отличии языковых параметров на компьютере, на котором выполняется код, от языковых параметров, используемых для тестирования этого кода. Поведение, ожидаемое при записи строковой операции, отличается от фактического поведения кода, выполняющегося на компьютере. Порядковое сравнение, напротив, зависит исключительно от двоичного значения сравниваемых символов.

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

Если в приложении необходимо выполнить строковую операцию с учетом языка и региональных параметров, на которую не влияет значение CurrentCulture, следует использовать метод, принимающий параметр CultureInfo. Для этого параметра необходимо задать значение свойства InvariantCulture. Для устранения языковых различий и гарантии непротиворечивых результатов это свойство нужно использовать с методами String.Compare и String.ToUpper. Дополнительные сведения об использовании свойства InvariantCulture для выполнения строковых операций без учета языка и региональных параметров см. в разделе Выполнение строковых операций, не зависящих от языка и региональных параметров.

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

Свойство InvariantCulture полезно для хранения данных, которые не будут отображаться для пользователей. Хранение данных в формате, не зависящем от языка и региональных параметров, гарантирует известный формат, который не изменяется. Когда пользователь из другой культуры получает доступ к данным, они могут быть форматированы способом, подходящим для этого пользователя. Например, если приложение сохраняет типы DateTime в текстовом файле, отформатированном для инвариантной культуры, то при вызове ToString для хранения строк оно должно использовать свойство InvariantCulture, а для извлечения строк – метод Parse. Это гарантирует неизменность базовых значений типов DateTime при чтении или записи данных пользователями из различных культур.

В следующем примере кода показана инициализация объекта CultureInfo с инвариантной культурой с помощью пустой строки ("") или InvariantCulture.

' The following lines are equivalent.
CultureInfo Invc = New CultureInfo("")
CultureInfo Invc = CultureInfo.InvariantCulture
// The following lines are equivalent.
CultureInfo Invc = New CultureInfo("");
CultureInfo Invc = CultureInfo.InvariantCulture;

В следующем примере кода показана запись объекта DateTime в файл в качестве строки, отформатированной для инвариантного языка и региональных параметров с использованием метода ToString. Затем происходит считывание строки из файла в формате инвариантного языка и региональных параметров и анализ в объекте DateTime с использованием метода Parse. Затем происходит форматирование объекта DateTime и отображение для культур "fr-FR" и "ja-JP".

Imports System
Imports System.IO
Imports System.Globalization
Imports Microsoft.VisualBasic

Public Class TextToFile
   Private const FILE_NAME As String = "MyDateFile.txt"   
   
   Public Shared Sub Main()
      If File.Exists(FILE_NAME) Then
         Console.WriteLine("{0} already exists!", FILE_NAME)
         Return
      End If

      Dim sw As StreamWriter = File.CreateText(FILE_NAME)
      
      'Creates a DateTime.
      Dim dtIn As DateTime = DateTime.Now
      Dim InvC As CultureInfo = CultureInfo.InvariantCulture
      ' Writes the string to the file formatted for InvariantCulture.
      sw.WriteLine(dtIn.ToString("d", InvC))
      sw.Close()
      
      If Not File.Exists(FILE_NAME) Then
         Console.WriteLine("{0} does not exist!", FILE_NAME)
         Return
      End If
      
      Dim sr As StreamReader = File.OpenText(FILE_NAME)
      Dim filedate As String
      filedate = sr.Readline()
      While Not filedate Is Nothing
         Console.WriteLine(ControlChars.Newline + "The date stored in _
            the file formatted for the invariant culture is:" + _
            ControlChars.Newline + " {0}", filedate )
         
         ' Creates a new DateTime and parses the 
         ' string stored in the file.
         Dim dtout as DateTime = DateTime.Parse(filedate, InvC)
         
         ' Creates a CultureInfo set to "fr-FR".
         Dim frc As New CultureInfo("fr-FR")
         ' Displays the date formatted for the "fr-FR" culture.
         Console.WriteLine(ControlChars.Newline + "The date read from _
            the file and formatted for the culture ""fr-FR"" is:" + _
            ControlChars.Newline + " {0}", dtout.ToString("d", frc))
         
         ' Creates a CultureInfo set to "ja-JP".
         Dim jpn As New CultureInfo("ja-JP")
         ' Displays the date formatted for the "ja-JP" culture.
         Console.WriteLine(ControlChars.Newline + "The date read from _
            the file and formatted for the culture ""ja-JP"" is:" + _
            ControlChars.Newline + " {0}", dtout.ToString("d", jpn))
        
        filedate = sr.Readline()
      End While
      
      Console.WriteLine(ControlChars.Newline + "The end of the stream _
         has been reached.")
      sr.Close()
   End Sub
End Class
using System;
using System.IO;
using System.Globalization;

public class TextToFile 
{
   private const string FILE_NAME = "MyDateFile.txt";
   public static void Main(String[] args) 
   {
      if (File.Exists(FILE_NAME)) 
      {
         Console.WriteLine("{0} already exists!", FILE_NAME);
         return;
      }
      StreamWriter sw = File.CreateText(FILE_NAME);
      
      // Creates a DateTime.      
      DateTime dtIn = DateTime.Now;
      // Creates a CultureInfo set to InvariantCulture.
      CultureInfo InvC = new CultureInfo("");
      // Converts dt to a string formatted for InvariantCulture,
      // and writes it to a file.
      sw.WriteLine (dtIn.ToString("d",InvC));
      sw.Close();

      if (!File.Exists(FILE_NAME)) 
      {
         Console.WriteLine("{0} does not exist!", FILE_NAME);
         return;
      }
      StreamReader sr = File.OpenText(FILE_NAME);
      String date;
      while ((date=sr.ReadLine())!=null) 
      {
         Console.WriteLine("\nThe date stored in the file formatted for 
               the invariant culture is:\n{0}" , date);    

         // Parses the string stored in the file,
         // and stores it in a DateTime.
         DateTime dtout = DateTime.Parse(date, InvC);

         // Creates a CultureInfo set to "fr-FR".
         CultureInfo frc = new CultureInfo("fr-FR");
         // Displays the date formatted for the "fr-FR" culture.
         Console.WriteLine("\nThe date read from the file and formatted 
               for the culture \"fr-FR\" is:\n{0}" , dtout.ToString("d", 
               frc));

         // Creates a CultureInfo set to "ja-JP".
         CultureInfo jpn= new CultureInfo("ja-JP");
         // Displays the date formatted for the "ja-JP" culture.
         Console.WriteLine("\nThe date read from the file and formatted 
               for the culture \"ja-JP\" is:\n{0}" , dtout.ToString("d", 
               jpn));
      }
      Console.WriteLine ("\nThe end of the stream has been reached.");
      sr.Close();
   }
}

В результате выполнения кода получены следующие выходные данные.

The date stored in the file formatted for the invariant culture is:
07/24/2001

The date read from the file and formatted for the culture "fr-FR" is:
24/07/2001

The date read from the file and formatted for the culture "ja-JP" is:
2001/07/24

The end of the stream has been reached.

См. также

Основные понятия

Использование класса CultureInfo