InvariantCulture プロパティの使用
更新 : 2007 年 11 月
InvariantCulture プロパティが表すカルチャは、ニュートラル カルチャと特定のカルチャのどちらでもありません。このプロパティは、カルチャに依存しない第 3 のカルチャの種類を表します。このプロパティには英語が関連付けられていますが、国または地域は関連付けられていません。アプリケーションでは、このプロパティを 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 オブジェクトとして解析されます。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.