推奨される国際対応アプリケーション開発手順
このセクションでは、推奨される国際対応アプリケーション開発手順について説明します。
推奨されるグローバリゼーション手順
アプリケーションを内部的に Unicode アプリケーションにします。
データの操作と書式指定には、System.Globalization 名前空間のカルチャ認識クラスを使用します。
- 並べ替えには SortKey クラスと CompareInfo クラスを使用します。
- 文字列比較には、CompareInfo クラスを使用します。
- 日付と時刻の書式指定には、DateTimeFormatInfo クラスを使用します。
- 数値書式指定には、NumberFormatInfo クラスを使用します。
- グレゴリオ暦とグレゴリオ暦以外の暦には、Calendar クラスまたは特定のカレンダー実装を使用します。
状況に応じて、System.Globalization.CultureInfo クラスのカルチャ プロパティ設定を使用します。 日付と時刻や数値の書式指定などの書式指定タスクには、CultureInfo.CurrentCulture プロパティを使用します。 リソースを取得するには、CultureInfo.CurrentUICulture プロパティを使用します。
CurrentCulture
プロパティとCurrentUICulture
プロパティはスレッドごとに設定できることに注意してください。System.Text 名前空間のエンコーディング クラスを使用して、アプリケーションでの各種エンコーディングのデータの読み取り操作と書き込み操作を有効にします。 常に ASCII データが使用されるとは限らないことに注意してください。 どのようなテキスト入力でも、各種の言語の文字が使用される可能性があります。 たとえば、アプリケーションは、サーバー名、ディレクトリ名、ファイル名、ユーザー名、および URL に含まれる各種言語の文字を受け入れる必要があります。
UTF8Encoding クラスを使用する場合は、セキュリティ上の理由から、このクラスに用意されているエラー検出機能を使用してください。 エラー検出機能を有効にするには、
throwOnInvalidBytes
パラメーターを受け取るコンストラクターを使用してクラスのインスタンスを作成し、このパラメーターの値をtrue
に設定します。文字列は、できるだけ全体を 1 つのまとまりとして扱い、個々の文字の連続として処理しないようにします。 これは特に部分文字列の並べ替えと検索で重要です。 これにより、組み合わせ文字の解析に関連する問題の発生を防ぐことができます。 System.Globalization.StringInfo クラスを使用することで 1 つの文字ではなくまとまったテキストを使用することもできます。
System.Drawing 名前空間のクラスを使用してテキストを表示します。
オペレーティング システム間での一貫性を維持するため、ユーザー設定によって CultureInfo がオーバーライドされないようにしてください。
CultureInfo
パラメーターを受け取るuseUserOverride
コンストラクターを使用し、このパラメーターをfalse
に設定してください。国際対応オペレーティング システムで、国際対応データを使用してアプリケーションの機能をテストします。
文字列比較操作または大文字と小文字の変更操作の結果に基づいてセキュリティ上の決定を行う場合は、カルチャに依存しない文字列操作を使用してください。 こうすることで、
CultureInfo.CurrentCulture
の値が結果に影響を及ぼすことがなくなります。 カルチャに依存した文字列比較により矛盾した結果がどのように生成されるかを示す例については、「文字列を使用するためのベスト プラクティス」の「現在のカルチャを使用する文字列比較」を参照してください。インターチェンジ (API 呼び出しの JSON ドキュメント内のフィールドなど) またはストレージに使用されている要素については、CultureInfo を使用します。さらに、ラウンドトリップ形式 (
"O"
、"o"
日時書式指定子など) を明示的に指定する必要があります。 インバリアント カルチャの書式指定文字列は安定しており、変更される可能性は低いですが、明示的な書式指定文字列を指定すると、コードの意図を明確にするのに役立ちます。- 日付/時刻の要素については、貴重な洞察を共有する Noda Time の著者 Jon Skeet のアドバイスと観察を検討してください。 詳細については、「Jon Skeet: Storing UTC is not a silver bullet」を参照してください。
グローバリゼーション データは安定していないため、これを念頭に置いてアプリケーションとそのテストを記述する必要があります。 これは、サポートされているすべてのプラットフォーム上のホスト OS チャネルを通じて年に数回更新されます。 通常、このデータはランタイムと共に配布されません。
推奨されるローカリゼーション手順
ローカライズ可能なすべてのリソースをリソース専用 DLL へ移動します。 ローカライズ可能リソースには、文字列、エラー メッセージ、ダイアログ ボックス、メニュー、埋め込みオブジェクト リソースなどのユーザー インターフェイス要素があります。
文字列やユーザー インターフェイス リソースをハードコーディングしないでください。
ローカライズできないリソースをリソース専用 DLL に含めないでください。 これにより、トランスレーターが混乱します。
文字列を実行時に連結して使う方法は避けてください。 連結される文字列は、英語の語順に依存することが多く、ほかの言語でのローカライズ作業が困難になります。
"Empty Folder" のように、構成要素の文法的な役割によって複数の翻訳が存在するあいまいな文字列を使用しないでください。 たとえば、"empty" は動詞または形容詞として解釈できるため、イタリア語やフランス語などの言語での翻訳結果が異なることがあります。
アプリケーションではテキストが含まれているイメージやアイコンを使用しないでください。 このようなイメージやアイコンのローカライズには時間と労力がかかります。
ユーザー インターフェイスの文字列は、表示領域に余裕がある程度の長さにしておいてください。 言語によっては、ユーザー インターフェイスが他の言語よりも 50 ~ 75% 長い領域を必要とする場合があります。
カルチャに基づいてリソースを取得するには、System.Resources.ResourceManager クラスを使用します。
Windows フォームのダイアログ ボックスを作成するには Visual Studio を使います。このように作成されたダイアログ ボックスは、Windows フォーム リソース エディター (Winres.exe) を使ってローカライズできます。 Windows フォームのダイアログ ボックスを手動でコーディングしないでください。
専門的なローカライズ (翻訳) 作業を計画してください。
リソースの作成とローカライズについて詳しくは、「.NET アプリのリソース」をご覧ください。
ASP.NET およびその他のサーバー アプリケーションのグローバリゼーションのベスト プラクティス
ヒント
ASP.NET Framework アプリのベスト プラクティスを次に示します。 ASP.NET Core アプリについては、「ASP.NET Core でのグローバリゼーションとローカリゼーション」 を参照してください。
CurrentUICulture プロパティおよび CurrentCulture プロパティをアプリケーションで明示的に設定します。 既定値には依存しないでください。
ASP.NET アプリケーションはマネージド アプリケーションであり、カルチャに基づいた情報の取得、表示、および操作では、ほかのマネージド アプリケーションと同じクラスを使用できます。
ASP.NET では次に示す 3 種類のエンコーディングを指定できる点に注意してください。
requestEncoding
は、クライアントのブラウザーから受信されたエンコードを指定します。responseEncoding
は、クライアント ブラウザーへ送信するエンコードを指定します。 ほとんどの場合、このエンコードはrequestEncoding
に指定されたエンコードと同じである必要があります。- fileEncoding は、.aspx、.asmx、.asax の各ファイルの解析の既定エンコードを指定します。
ASP.NET アプリケーションの次の3つの場所に、
requestEncoding
、responseEncoding
、fileEncoding
、culture
およびuiCulture
属性の値を指定します:- Web.config ファイルのグローバリゼーション セクション内。 Web.config ファイルは、ASP.NET アプリケーションの外部ファイルです。 詳しくは、「<globalization> 要素」をご覧ください。
- ページ ディレクティブ。 アプリケーションがページを処理している時点では、ファイルは既に読み取られています。 そのため、fileEncoding と requestEncoding を指定するには遅すぎます。 ページディレクティブで指定できるのは、
uiCulture
、culture
、responseEncoding
のみである。 - アプリケーション コード (プログラムで指定)。 この設定は、要求ごとに変更できます。 ページ ディレクティブの場合と同様に、アプリケーション コードの処理時点では、
fileEncoding
とrequestEncoding
の指定は遅すぎます。 アプリケーションコードに指定できるのは、uiCulture
、culture
、およびresponseEncoding
のみです。
uiCulture 値には、ブラウザー受け入れ言語を設定できます。
分散されたアプリケーションの場合は、ダウンタイムなしの更新 (Azure Container Apps など) などを許可します。異なる形式規則やその他のカルチャ データ、特にタイム ゾーン ルールを持つアプリケーションの複数のインスタンスが存在する可能性がある状況を計画する必要があります。
- アプリケーションのデプロイにデータベースが含まれている場合は、データベースに独自のグローバリゼーション規則があることを覚えておいてください。 ほとんどの場合、データベースでグローバリゼーション関連の関数を実行しないようにする必要があります。
- アプリケーションのデプロイにクライアント グローバリゼーション リソースを使用するクライアント アプリケーションまたは Web フロントエンドが含まれている場合は、クライアント リソースがサーバーで使用可能なリソースと異なると想定します。 クライアントでグローバリゼーション関数のみを実行することを検討してください。
堅牢なテストに関する推奨事項
依存関係をより明示的にし、テストが簡単かつ並列化できるようにするには、書式設定を実行するメソッドに
CultureInfo
パラメーターなどのカルチャ関連の設定を明示的に渡し、日付と時刻を処理するメソッドにTimeZoneInfo
を明示的に渡すことを検討する必要があります。 時刻を取得するときは、TimeProvider または同様の型を使用する必要があります。ほとんどのテストでは、特定の書式設定操作の正確な出力やタイム ゾーンの正確なオフセットを明示的に検証する必要はありません。 書式設定とタイム ゾーン データはいつでも変更される可能性があり、それ以外の場合はオペレーティング システムの 2 つの同一インスタンス (および同じコンピューター上のプロセスが異なる可能性があります) 間で異なる場合があります。 正確な値に依存すると、テストが脆弱になります。
- 一般に、一部の出力が受信されたことを検証するだけで十分です (書式設定時に空でない文字列など)。
- 一部のデータ要素と形式では、データが入力値に解析されることを検証する (ラウンドトリップ) 場合があります。 フィールドが削除された場合 (たとえば、一部の日付関連フィールドの年) や、値が切り捨てられたり丸められたりする場合 (浮動小数点出力など) には注意が必要です。
- ローカライズされたすべての形式の出力を検証するための明示的な要件がある場合は、テストのセットアップ中にカスタム カルチャを作成して使用することを検討する必要があります。 ほとんどの単純なケースでは、コンストラクター
new CultureInfo(..)
を使用してCultureInfo
オブジェクトをインスタンス化し、DateTimeFormat
プロパティとNumberFormat
プロパティを設定することで、これを行うことができます。 より複雑なケースでは、型をサブクラス化すると、追加のプロパティをオーバーライドできます。 これには、リソース ファイルで擬似ローカリゼーションを有効にするなど、その他の利点が考えられる場合があります。 - すべての日付/時刻操作の結果を検証するための明示的な要件がある場合は、テストのセットアップ中にカスタム
TimeZoneInfo
インスタンスを作成して使用することを検討する必要があります。 これには、特定のエッジ ケース (DST 規則の変更など) の安定したテストを可能にするなど、追加の利点が考えられます。
関連項目
.NET