一般的にどちらを使用するのが最善ですか— StringComparison.OrdinalIgnoreCaseまたはStringComparison.InvariantCultureIgnoreCase?


161

私はこのようないくつかのコードを持っています:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

私はその事件を気にしません。私が使用する必要がありますOrdinalIgnoreCaseInvariantCultureIgnoreCaseまたはCurrentCultureIgnoreCase


2
これをチェックして、このスレッドにとって本当に便利です。比較のためにordianlignorecaseを使用するという私の提案。blogs.msdn.com/b/noahc/archive/2007/06/29/...
UmaMaheswaran


全体として、比較する対象の種類によって大きく異なります。具体的には、文化に依存するユーザー入力や内部的なものです。PCのカルチャが内部コード文字列の比較をめちゃくちゃにしたくない。
Nyerguds

回答:


179

新しい.Net Docsには、状況に応じて最適なものを決定するのに役立つ表が追加されました。

MSDNの「Microsoft .NET 2.0で文字列を使用するための新しい推奨事項」から

概要:以前InvariantCultureに文字列の比較、大文字小文字の区別、並べ替えにを使用していたコード所有者はString、Microsoft .NET 2.0で新しいオーバーロードのセットを使用することを強く検討する必要があります。具体的には、文化にとらわれず、言語的に無関係になるように設計されたデータは、新しい列挙のStringComparison.OrdinalまたはStringComparison.OrdinalIgnoreCaseメンバーのいずれかを使用して、オーバーロードの指定を開始する必要がありStringComparisonます。これらstrcmpは、本質的にシンボリック文字列の言語解釈によるバグを回避するだけでなく、より良いパフォーマンスを提供するのと同様に、バイトごとの比較を強制します。


126
それらが異なる例を示すために、2つの文字列"Straße"とを考えます"STRASSE"。戻り値を使用OrdinalIgnoreCaseする場合、それは等しいと言います。EqualsfalseInvariantCultureIgnoreCase
Jeppe Stig Nielsen


63

それはすべて依存します

ユニコード文字列の比較は難しいです:

テキスト処理ソフトウェアでのUnicode文字列の検索と比較の実装では、同等のコードポイントの存在を考慮する必要があります。この機能がない場合、特定のコードポイントシーケンスを検索するユーザーは、異なるが、標準的には同等のコードポイント表現を持つ他の視覚的に区別できないグリフを見つけることができません。

参照:http : //en.wikipedia.org/wiki/Unicode_equivalence


大文字と小文字を区別しない方法で2つのUnicode文字列を比較しようとしていて、それをEVERYWHEREで機能させたい場合は、不可能な問題があります。

古典的な例はトルコ語のiで、大文字にするとİ(ドットに注意)になります。

デフォルトでは、.Netフレームワークは通常、文字列関連の関数にCurrentCulture.Equals使用しますが、序数(バイト単位)比較を使用するという非常に重要な例外があります。

これにより、設計上、コンピュータのカルチャに応じて動作が異なるさまざまな文字列関数が生成されます。


それでも、「一般的な目的」で、大文字と小文字を区別せずに比較したい場合があります。

たとえば、アプリケーションがインストールされているコンピューターに関係なく、文字列比較を同じように動作させることができます。

これを実現するには、3つのオプションがあります。

  1. カルチャを明示的に設定し、Unicode等価ルールを使用して大文字と小文字を区別しない比較を実行します。
  2. カルチャをインバリアントカルチャに設定し、Unicodeの等価ルールを使用して大文字と小文字を区別しない比較を実行します。
  3. OrdinalIgnoreCaseを使用します。これは、InvariantCultureを使用して文字列を大文字にしてから、バイトごとの比較を実行します。

Unicode正規化ルールは、より高価である手段方法1)または2を使用して)、複雑ですOrdinalIgnoreCaseOrdinalIgnoreCase特別なユニコード正規化を実行しないという事実は、コンピューター画面で同じようにレンダリングされる一部の文字列は同一とは見なされないことを意味します。たとえば、次のように"\u0061\u030a""\u00e5"の両方åレンダリングします。ただし、序数比較では異なると見なされます。

どちらを選択するかは、構築するアプリケーションによって大きく異なります。

  • トルコのユーザーのみが使用する基幹業務アプリを作成している場合は、必ず方法1を使用します。
  • 単純な "偽の"大文字と小文字を区別しない比較が必要な場合、たとえば、通常は英語であるdbの列名は、おそらく方法3を使用します。

マイクロソフトには、明確なガイドラインを含む一連の推奨事項があります。ただし、これらの問題に取り組む前に、Unicodeの同等性の概念を理解することは本当に重要です。

また、OrdinalIgnoreCaseは非常に特殊な種類の獣であることを覚えておいてください。それは、辞書式のいくつかの混合されたものと少し序数を比較して選ぶことです。これは混乱を招く可能性があります。


4

状況次第ではないでしょうか。序数比較は実際には文字のUnicode値を調べているため、アルファベット順に並べ替える場合は最適な選択ではありません。ただし、文字列比較の場合、序数の方が少し速くなります。


1

あなたがしている場合を除き、私はにInvariantCultureから敬遠したいけれどもそれは、あなたが望むものに依存して非常にあなたが他の言語のコードをローカライズすることは決してないだろう。代わりにCurrentCultureを使用してください。

また、OrdinalIgnoreCaseは数値を尊重する必要があります。これは、必要な場合とそうでない場合があります。


1
混合言語環境でVB6コードを記述したことはありますか?フォームリソースに格納されている数値は現在のロケールの形式を使用するため、フランスロケールのPCではコンパイルできるが、英語ロケールのPCではコンパイルできないコードを作成できます。私はあなたが反対のアプローチを取る必要があると主張します:あなたが現在の文化を使うときは非常に注意してください。カルチャ間でデータが移動しても、システムが引き続き機能するかどうかを常に考えてください。タイムゾーンも同じです。
Wim Coenen、2010

「依存する」という答えには同意します。「リスペクト番号」のビットに従っていないのですか?
Sam Saffron

-1

非常に簡単な答えは、トルコ語を使用しているのでなければ、InvariantCultureを使用する必要はないということです。

次のリンクを参照してください。

C#でToUpper()とToUpperInvariant()の違いは何ですか?


5
この答えは単純かもしれませんが、それも非常に間違っています。トルコ語の「私」は一例にすぎず、さらに多くの落とし穴があります。
Ohad Schneider

さらに落とし穴?私はトルコの問題の事例を知っています。
HelloWorld 2016

うん、トルコ語に加えてアゼリがある。しかし、それだけです。
ジムバルター2017年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.