C#の大文字と小文字を区別しない等号演算子はありますか?


156

以下は大文字と小文字が区別されることを知っています。

if (StringA == StringB) {

では、2つの文字列を無差別に比較する演算子はありますか?



誰かがこの質問を見つけて、Dictionary <string、int>の大文字と小文字を区別しない比較を探している場合は、ここでこの質問を確認してください。汎用辞書の大文字と小文字を区別しないアクセス
Robotnik

それは本当に素晴らしいでしょう。対応~=するparallel ==を大文字と小文字を区別しないバージョンとして定義するとします。
eidylon 2017

マイクロソフトの開発者がこれを見た場合、csharpの次のバージョンでは大文字と小文字を区別しない演算子が必要になると思います。このstring.Equal()は長いです。
Rez.Net

回答:


288

これを試して:

string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);

私は相対的なStackOverflowの初心者です-リンクを追加することで何を意味するのか説明できますか?MSDNドキュメントを意味しますか?
John Feminella、2009年

55
カルチャに依存した比較が必要な場合は、この方法を使用してください。「FILE」と「file」の両方が受け入れられることを確認したい場合は、「OrdinalIgnoreCase」を使用してください。そうしないと、コードがトルコ語のロケールのような場所で機能しない可能性があります。詳細については、moserware.com / 2008/02 / does
Jeff Moser

10
サミュエルが何について話しているのかわからない...この答えは完璧です。その正しいと自明です。参照は必要ありません。+1
セーリング柔道

3
これはひどい一口です!キーボードがすり減ります。「if A$=B$ then goto 10」を使用できる時代は過ぎ去った
Sanjay Manohar 2012年

9
@Sanjay Manohar次に、カスタムオペレーターを記述します。より良いキーボードをお勧めします。
Rushyo 2012

37

文字の大文字と小文字を無視して2つの文字列を比較する最良の方法は、序数を無視する大文字と小文字の文字列比較を指定するString.Equals静的メソッドを使用することです。これは最速の方法でもあり、文字列を小文字または大文字に変換してから比較するよりもはるかに高速です。

私は両方のアプローチのパフォーマンスをテストし、通常の無視の場合の文字列比較は9倍以上高速でした!また、文字列を小文字または大文字に変換するよりも信頼性が高くなります(トルコ語のi問題を確認してください)。したがって、常にString.Equalsメソッドを使用して、文字列が等しいかどうかを比較します。

String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);

カルチャ固有の文字列比較を実行する場合は、次のコードを使用できます。

String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);

2番目の例では、現在のカルチャの文字列比較ロジックを使用するため、最初の例の「通常の大文字と小文字を区別しない」比較よりも遅くなることに注意してください。最大のパフォーマンスが得られたら、「通常の大文字と小文字を区別しない」比較を使用します。

詳細については、ブログの全文をお読みください。


1
提案しないでください。ToLowerまたはToLowerInvariant、比較を実行するためだけにメモリを作成します。Unicodeに新しい文字セットが追加されると、失敗する可能性があります。ToUpper特にトルコ語の「i」のために失敗します。ToLower同様の理由で将来失敗しない理由はありません。
antiduh、

@antiduh、コメントありがとうございます。私たちのほとんどは、これらの潜在的な問題を認識しています。インターネット上の多くのチュートリアルでは、例としてトルコ語の「i」を紹介しています。私の投稿でご覧のとおり、ToLowerまたはToLowerInvariantメソッドを使用することはお勧めしませんString.Equals。メソッドがいかに効率的かを示したかっただけです。
Pavel Vladov、2015年

3
「私たちの多くはこれらの潜在的な問題を認識しています。インターネット上の多くのチュートリアルでは、例としてトルコ語の「i」を挙げています」-十分な人がいないため、回答の2番目の文として言及しています。さらに、あなたの答えはそれを決して使用しないための十分な正当化を含みません-あなたは単にパフォーマンスについて言及します。パフォーマンスが常に最優先事項であるとは限りません。その結果、現在ヘルプセンターのガイドラインに違反しています。外部サイトへのリンクは問題ありませんが、コンテンツを十分に要約していません(トルコ語の「i」問題)。SOは広告プラットフォームではありません。
antiduh

20

StringComparer静的クラスには、必要に応じて大文字と小文字を区別するタイプの比較子を返すプロパティがいくつかあります。

StringComparer プロパティ

たとえば、あなたは呼び出すことができます

StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)

または

StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)

引数を取るオーバーロードstring.Equalsstring.Compareオーバーロードよりも少しクリーンですStringComparison


15
System.Collections.CaseInsensitiveComparer

または

System.StringComparer.OrdinalIgnoreCase

これはアプリケーション全体に影響しますか?
GateKiller 2009年

3
これに関する詳細情報はどこにありますか?これは、大文字と小文字を区別しない一致に==を使用できることを意味しますか?
GateKiller 2009年


8

または

if (StringA.Equals(StringB, StringComparison.CurrentCultureIgnoreCase)) {

ただし、StringAがnullでないことを確認する必要があります。したがって、おそらくより良いtuの使用:

string.Equals(StringA , StringB, StringComparison.CurrentCultureIgnoreCase);

ジョンが示唆したように

編集:バグを修正しました



3

オペレーター?いいえ、ただし、文字列の比較で大文字と小文字を区別しないようにカルチャを変更できると思います。

// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo

これにより、equals演算子による文字列の比較方法が変わると確信しています。


ええ、控えめに言っても、すべての文字列比較で大文字と小文字を区別したくない場合を除き、それはあなたがしたいことではありません。しかし、それはequals演算子の動作を変更すると思います。
John Leidegren 2009年

3

ここで構文を簡略化するアイデア:

public class IgnoreCase
{
    private readonly string _value;

    public IgnoreCase(string s)
    {
        _value = s;
    }

    protected bool Equals(IgnoreCase other)
    {
        return this == other;
    }

    public override bool Equals(object obj)
    {
        return obj != null &&
               (ReferenceEquals(this, obj) || (obj.GetType() == GetType() && this == (IgnoreCase) obj));
    }

    public override int GetHashCode()
    {
        return _value?.GetHashCode() ?? 0;
    }

    public static bool operator ==(IgnoreCase a, IgnoreCase b)
    {
        return string.Equals(a, b, StringComparison.OrdinalIgnoreCase);
    }

    public static bool operator !=(IgnoreCase a, IgnoreCase b)
    {
        return !(a == b);
    }

    public static implicit operator string(IgnoreCase s)
    {
        return s._value;
    }

    public static implicit operator IgnoreCase(string s)
    {
        return new IgnoreCase(s);
    }
}

次のように使用可能:

Console.WriteLine((IgnoreCase) "a" == "b"); // false
Console.WriteLine((IgnoreCase) "abc" == "abC"); // true
Console.WriteLine((IgnoreCase) "Abc" == "aBc"); // true
Console.WriteLine((IgnoreCase) "ABC" == "ABC"); // true

見た目はすっきりした構文が好きですが、少し誤解を招く(IgnoreCasevs IgnoreCaseString)あいまいです(Javaは暗黙的なボックス化解除と暗黙的なボックス化を選択するため、Javaでこれを暗黙的にキャストして文字列に戻すことはできない思います)。そして、これにより、2つの新しいオブジェクトのメモリオーバーヘッドが作成され、比較ごとにコールツリーが実行され、表示された使用例のいくつかのネストされたメソッド呼び出しにジャンプします。とはいえ、ほとんどの場合、パフォーマンスはおそらく十分です。
Arkaine55

これは賢いアイデアですが、保守性の観点からはあまり賢明ではありません。システムの組み込み文字列型を使用する代わりに、代理文字列型を効果的に作成しています。来たばかりのプログラマーは、一目で何が起こっているのか理解できず、彼/彼女はあなたを怒鳴りつけます。string.Equals()を使用することはそれほど悪いことではなく、ほとんどの人はそれが何をしているのか理解するでしょう。
ntcolonel

1

私はこれらの比較方法の最後に入力することに慣れています: , StringComparison.

だから私は拡張を行いました。

namespace System
{   public static class StringExtension
    {
        public static bool Equals(this string thisString, string compareString,
             StringComparison stringComparison)
        {
            return string.Equals(thisString, compareString, stringComparison);
        }
    }
}

thisStringextを呼び出す前にnullを確認する必要があることに注意してください。


1
これは、現在の.NET Frameworkバージョンの組み込みメソッドと同じですか? docs.microsoft.com/en-gb/dotnet/api/…–
Bernard Vander

1
そのように表示されます。.netの新しいバージョンにはこれが含まれているようです。
Valamas 2018年

.NET 4.5以降およびすべての.NET Coreバージョン以降で使用できます。
Bernard Vander Beken


0
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {

人々は、ToUpperInvariant()がToLowerInvariant()よりも速いと報告しています。


1
現在または希望するカルチャに大文字の特別なルールがある場合、不変条件は悪い考えかもしれません。
OregonGhost 2009年

これは各文字列の新しいコピーを作成しますか?もしそうなら、悪い考え。
日中韓

1
また、どちらか(または両方)の文字列がnullの場合も例外がスローされます。
tvanfosson 2009年

3
パフォーマンスに関しては、ここでも2つの新しい文字列インスタンスを作成するため、これはあまり良いソリューションではありません。
Frederik Gheysels 2009年

0

他の答えはここでは完全に有効ですが、どういうわけか入力StringComparison.OrdinalIgnoreCaseしてを使用するのにも時間がかかりますString.Compare

単純な文字列拡張メソッドをコーディングしました。ブール値を使用して、比較で大文字と小文字を区別するか、区別しないかを指定できます。次の回答を参照してください。

https://stackoverflow.com/a/49208128/2338477

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.