使用 InvariantCulture 属性

更新:2007 年 11 月

InvariantCulture 属性既不表示非特定区域性,也不表示特定区域性。它表示第三种类型的区域性,即不区分区域性的区域性。它与英语语言关联,但不与任何国家/地区关联。在应用程序中,System.Globalization 命名空间内几乎所有要求区域性的方法,都可以使用此属性。但是,应用程序只应将固定区域性用于需要与区域性无关的结果的进程,如对保存到文件中的数据进行格式设置和分析。在其他情况下,它所产生的结果可能在语言上不正确或在文化上不合适。

安全注意事项

如果安全决策将根据字符串比较或大小写更改的结果作出,则应用程序应使用忽略大小写的序号比较,而不应使用 InvariantCulture。Compare() 和 ToUpper 等方法的默认实现使用 CurrentCulture 属性。如果更改了 CurrentCulture,或者运行代码的计算机上的区域性与用于测试代码的区域性不同,则执行区分区域性的字符串操作的代码可能导致安全漏洞。编写字符串操作时的预期行为与代码在执行计算机上的实际行为不同。相比之下,序号比较仅取决于比较的字符的二进制值。

字符串操作

如果应用程序需要执行不受 CurrentCulture 的值影响且区分区域性的字符串操作,则应使用接受 CultureInfo 参数的方法。应用程序应为此参数指定 InvariantCulture 属性值。应用程序应将此属性用于 Compare() 和 ToUpper 等方法,以便消除区域性差异,确保结果一致。有关使用 InvariantCulture 属性来执行不区分区域性的字符串操作的更多信息,请参见不区分区域性的字符串操作

保存数据

如果要存储不直接显示给用户的数据,则 InvariantCulture 属性十分有用。以与区域性无关的格式存储数据可以保证已知格式不会发生更改。当不同区域性的用户访问数据时,数据可以针对特定用户进行相应格式化。例如,如果应用程序在文本文件中存储的 DateTime 类型已进行了固定区域性格式化,则在调用 ToString 来存储字符串以及调用 Parse 方法来检索字符串时,应用程序应使用 InvariantCulture 属性。 采用这种方法,可确保当不同区域性的用户读取或写入数据时,DateTime 类型的基础值不会发生更改。

下面的代码示例演示如何用空字符串 ("") 或 InvariantCulture 来初始化具有固定区域性的 CultureInfo 对象。

' 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;

下面的代码示例演示如何用 ToString 方法将 DateTime 对象作为一个固定区域性格式化字符串写入文件。然后,以固定区域性格式从文件中读取该字符串,并使用 Parse 方法将其分析为 DateTime 对象。然后,针对区域性“fr-FR”和“ja-JP”格式化并显示 DateTime 对象。

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 类