C の文字列を比較する#

Tip

この記事は、少なくとも 1 つのプログラミング言語を既に知っており、C# を学習している開発者向けの 基礎 セクションの一部です。 プログラミングを初めて使用する場合は、最初に「 はじめ に」チュートリアルから始めてください。

別の言語から来ていますか? 文字列の C# ==は、Javaのや JavaScript のequalsと同様に、参照ではなく===を比較します。 主な違いは、C# では、値を使用して序数 (バイナリ) とStringComparison比較を選択できる点です。

文字列を比較して、次の 2 つの質問のいずれかに答えます。 これら 2 つの文字列は等しいか、 または これらの文字列はどのような順序で並べ替えられますか? C# では、いずれかの質問に答えるときに 2 つの独立した要因を制御できます。

  • 大文字と小文字の区別"Hello""hello" が等しいとして扱われるかどうか。
  • 比較の種類ordinal(各文字のバイナリ値を比較する)または カルチャを考慮する(カルチャの言語規則を適用する)。

StringComparison列挙は、これらの要素を比較メソッドに渡す 1 つの値に結合します。

等しいかどうかを比較する

String.Equals メソッドと == 演算子はどちらも、既定で大文字と小文字を区別する序数比較を実行します。 序数比較では、各文字のバイナリ値がチェックされるため、高速になり、すべてのコンピューターで同じ結果が得られます。 StringComparison値を受け取るオーバーロードを呼び出すことによって、意図を明示的にすることができます。

string root = @"C:\users";
string root2 = @"C:\Users";

// Equals and == both perform a case-sensitive, ordinal comparison.
Console.WriteLine(root.Equals(root2));
// => False
Console.WriteLine(root == root2);
// => False

// Pass a StringComparison value to state the intent explicitly.
Console.WriteLine(root.Equals(root2, StringComparison.Ordinal));
// => False

大文字と小文字を無視しつつ序数の意味を維持するには、StringComparison.OrdinalIgnoreCase を渡します。

string root = @"C:\users";
string root2 = @"C:\Users";

// OrdinalIgnoreCase compares the binary values but ignores case.
bool equalIgnoringCase = string.Equals(root, root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(equalIgnoringCase);
// => True

並べ替え順序を比較する

等価性ではなくソート順序を決定するには、String.Compareを使用します。 1 番目の文字列が 2 番目の文字列と同じ位置、または 2 番目の文字列の後で並べ替えられるかどうかを示す、負の数、0、または正の数値を返します。

string first = "Avocado";
string second = "Banana";

// Compare returns a negative number, zero, or a positive number
// to indicate sort order. Specify the comparison type explicitly.
int order = string.Compare(first, second, StringComparison.Ordinal);
Console.WriteLine(order < 0
    ? $"'{first}' sorts before '{second}'."
    : $"'{first}' sorts at or after '{second}'.");
// => 'Avocado' sorts before 'Banana'.

Important

CompareCompareTo は既定では カルチャを考慮した 比較になりますが、Equals== は既定では 序数比較 になります。 驚きを避けるには、明示的な StringComparison 値を渡して、必要な動作をコードに示します。

パターン マッチングで定数を is または switch と比較する

比較対象の値が定数の場合は、 is 演算子 を定数 パターン と共に使用して、 ==の読み取り可能な代替手段として使用できます。

string status = "Ready";

// When the right operand is a constant, the is operator and a
// constant pattern read as an alternative to ==.
if (status is "Ready")
{
    Console.WriteLine("The system is ready.");
}
// => The system is ready.

文字列を複数の定数と比較するには、 switchを使用します。 各アームは 定数パターンをテストし、破棄パターン (_) は一致しないすべての値を処理します。 次の例では、方向キーワードを移動命令にマップします。

foreach (string heading in new[] { "North", "South", "East", "West", "NE" })
{
    // A switch expression matches each constant pattern in turn and
    // returns the first match. The discard (_) handles every other value.
    string instruction = heading switch
    {
        "North" => "Travel due North for 10 km.",
        "South" => "Travel due South for 10 km.",
        "East" => "Travel due East for 10 km.",
        "West" => "Travel due West for 10 km.",
        _ => $"Unknown heading: {heading}.",
    };
    Console.WriteLine(instruction);
}
// => Travel due North for 10 km.
// => Travel due South for 10 km.
// => Travel due East for 10 km.
// => Travel due West for 10 km.
// => Unknown heading: NE.

文字列定数をテストする switch 式は、 ==と同じ大文字と小文字を区別する序数比較を実行するため、 "north""North" arm と一致しません。

適切な比較を選択する

習慣からではなく、データに基づいて比較の種類を選択します。

  • 識別子、ファイル パス、プロトコル トークン、およびその他の機械的に定義されたテキストには、Ordinal(または大文字と小文字を無視するには OrdinalIgnoreCase)を使用します。 序数比較は高速で、カルチャに関係なく一貫した結果が得られます。
  • ユーザーが読み取って並べ替えるテキスト (名前や製品タイトルなど) の場合は、 CurrentCulture を使用して、注文がユーザーの期待と一致するようにします。

カルチャに対応した比較では、カルチャによって異なる言語ルールが適用され、驚くべき結果が生成される可能性があります。 たとえば、一部のカルチャでは、 "ss""ß" が等しく扱われ、文字列の順序がマシン間で変化する可能性があります。 こうしたばらつきがあるため、カルチャを考慮した比較は真の自然言語テキストに対してのみ使用し、コレクションに対して並べ替えと検索の両方を行う場合は常に同じ種類の比較方法を使用してください。

グローバリゼーションの考慮事項やプラットフォームの違いなど、カルチャに依存する比較の詳細な処理については、「.NETの文字列を比較するためのベスト プラクティス」を参照してください。

こちらも参照ください