大文字と小文字を区別しない文字列比較を行うにはどうすればよいですか?


217

下の行で大文字と小文字を区別しないようにするにはどうすればよいですか?

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username == (string)drUser["Username"]) != -1);

今日私は使用を提案するいくつかのアドバイスを今日与えられました:

x.Username.Equals((string)drUser["Username"], StringComparison.OrdinalIgnoreCase)));

問題は、これを機能させることができないことです。以下の行を試しましたが、これはコンパイルされますが、誤った結果が返されます。

drUser["Enrolled"] = 
      (enrolledUsers.FindIndex(x => x.Username.Equals((string)drUser["Username"], 
                                 StringComparison.OrdinalIgnoreCase)));

誰でも問題を指摘できますか?


1
どのようなデータ型にする必要drUser["Enrolled"]がありますか?ブール値のように見えFindIndex()ますが、インデックスを返します。そのユーザーのインデックスが0の場合、0を返しますが、これはfalseである可能性があります。いつ、実際には本当です。Exists()この方法は、この場合には良いかもしれません。
drharris

もう一方のフィールドにない書式設定の時間や余分なスペースがないと確信していますか?
joshlrogers、2010年

1
FindIndex(およびテスト)の代わりにenrolledUsers.Any()を使用することをお勧めします。
Marc

回答:


405

これは、.NETフレームワーク(4&+)で同等性をチェックするためのベストプラクティスではありません

String.Compare(x.Username, (string)drUser["Username"], 
                  StringComparison.OrdinalIgnoreCase) == 0

代わりに以下を使用してください

String.Equals(x.Username, (string)drUser["Username"], 
                   StringComparison.OrdinalIgnoreCase) 

MSDNの推奨事項:

  • String.Equalsメソッドのオーバーロードを使用して、2つの文字列が等しいかどうかをテストします。
  • 使用String.CompareString.CompareTo 、文字列をソートする方法を等価性をチェックしません

8
あなたは使うべきstring.CompareではありませんString.Compare
フレッド

5
@フレッド同意しますが、理由を教えてください。
Gusdor 2016年

22
@フレッド私は「スタイルコップがそう言っているから」というよりは技術的な理由を期待していた。何か不足していますか?
Gusdor 2016年

12
string.compareとstring.Compareの違いはありません。文字列の同義語System.Stringクラスです。メンバーCompareは拡張メソッドです。@ Fred @Gusdor
Nuri YILMAZ

23
@Gusdor stringString、言語のキーワードであるためより優れています。一つには、String以外のものかもしれないSystem.Stringのに対し、string缶はできません。また、技術的にはC#ではなく.NETの一部ですstringが、C#に存在することが多少保証されていStringます。
Dave Cousineau 2017

36

String.Compare次のような静的関数を使用する必要があります

x => String.Compare (x.Username, (string)drUser["Username"],
                     StringComparison.OrdinalIgnoreCase) == 0

6
いいえ、のString.Equals代わりに使用する必要がありますString.Compare。どちらが大きいかを計算する必要はありません。等しくないということだけです。
ErikE

@ErikE:あと6年でどの方法を使用することをお勧めしますか:-)
Oleg

3
不思議ではない!等価のセマンティクスが必要な場合は等価を使用し、比較のセマンティクスが必要な場合は比較を使用することをお勧めします。何がそんなに難しいのですか?同じことIEquatableIComparableしないでください。一方を実装するクラスを使用できますが、もう一方を実装しても意味がありません。たとえば、センサーサンプリングを時間順に並べ替えることができます(IComparable)。そして、物事が等しい(IEquatable)かどうかを示すことはできますが、順序付けしても意味がありません(たとえば、コンピューターのシリアル番号)。
ErikE

@ErikE:あなたは私の見解を理解していません。古い答えは執筆の時間に対応します。古い答えには触れないでください。ほとんどの製品に当てはまります。ベストプラクティスまたはパフォーマンスの観点からの最良の選択は、後で何度も変更できます。古い答えについて話し合う意味がありません。
Oleg

18
申し訳ありませんが、コメントの正確さについての批評として捉えました。あなたが言っていることが古い答えが最高のものではないかもしれないことを認めているということなら、それから素晴らしい!しかし、私は古い答えについてあなたに同意しなければなりません。貧しい人々の情報を与える古い答えはする必要があり、上のコメントされなければならない彼らはまだ通知されているため、ダウン投票され、今日の読者を。
ErikE

27

これを比較に使用してください:

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

10
CurrentCultureIgnoreCaseとOrdinalIgnoreCaseを使用する利点と落とし穴に注意してください。カルチャ比較のセマンティクスが必要ない場合は、パフォーマンスをいくつか節約し、序数比較を使用してください。
ErikE

7

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

単純な文字列拡張メソッドをコーディングしました。ここでは、比較で大文字と小文字を区別するか、ブールで大文字と小文字を区別しないかを指定できます。コード全体をここに添付します。

using System;

/// <summary>
/// String helpers.
/// </summary>
public static class StringExtensions
{
    /// <summary>
    /// Compares two strings, set ignoreCase to true to ignore case comparison ('A' == 'a')
    /// </summary>
    public static bool CompareTo(this string strA, string strB, bool ignoreCase)
    {
        return String.Compare(strA, strB, ignoreCase) == 0;
    }
}

その後、全体の比較は約10文字短くなります-比較:

文字列拡張を使用する前に:

String.Compare(testFilename, testToStart,true) != 0

文字列拡張を使用した後:

testFilename.CompareTo(testToStart, true)

2
名前付けに同意しません。比較はソフトウェア開発でよく知られている機能であり、あなたは基本的に機能を変更しました。比較のようなintを返すか、名前を別の名前、たとえば「IsEqual」に変更する必要があると思います。
Fred

7

(論争はありますが)System.String大文字と小文字を区別しない比較拡張メソッドを提供するように拡張できます。

public static bool CIEquals(this String a, String b) {
    return a.Equals(b, StringComparison.CurrentCultureIgnoreCase);
}

そのように使用します:

x.Username.CIEquals((string)drUser["Username"]);

C#を使用すると、プロジェクトで構文シュガーとして機能する拡張メソッドを作成できます。

それは答えではなく、私はこの質問が古くて解決されていることを知っています、私はこれらのビットを追加したかっただけです。


3

私はあなたがこのリンクでより多くの情報を見つけると思います:

http://codeidol.com/community/dotnet/controlling-case-sensitiveivity-when-comparing-two-st/8873/

2つの文字列を比較するには、StringクラスのCompare静的メソッドを使用します。比較で大文字と小文字が区別されるかどうかは、そのオーバーロードの1つの3番目のパラメーターによって決まります。例えば:

string lowerCase = "abc";
string upperCase = "AbC";
int caseInsensitiveResult = string.Compare(lowerCase, upperCase,
  StringComparison.CurrentCultureIgnoreCase);
int caseSensitiveResult = string.Compare(lowerCase,
  StringComparison.CurrentCulture);

caseSensitiveResultの値は-1(lowerCaseがupperCaseより「小さい」ことを示す)であり、caseInsensitiveResultはゼロ(lowerCaseがupperCaseに「等しい」ことを示す)です。


1

StringComparison.CurrentCultureIgnoreCase代わりに使用してみませんか?


5
-1:この答えは不十分です。@ ocean4dreamの回答をご覧ください:stackoverflow.com/a/13965429/109941
ジムG.

@decyclone:OrdinalIgnoreCaseよりも遅いですが、場合によっては関連があります。したがって、-1は指定しません。stackoverflow.com/questions/2749662/…–
Csaba Toth


1

EqualsIgnoreCaseの拡張メソッドを記述したい

public static class StringExtensions
{
    public static bool? EqualsIgnoreCase(this string strA, string strB)
    {
        return strA?.Equals(strB, StringComparison.CurrentCultureIgnoreCase);
    }
}

-11

あなたはいつでも関数を使うことができます:.ToLower(); .ToUpper();

文字列を変換して比較します...

幸運を


これで彼の問題が解決するとは思いません。また、この質問はすでに4年以上前のものであることを示します。
VojtěchDohnal

7
これは新しい文字列を作成するので、これは非常に非効率的だと思います。この新しい文字列を作成するには、すべての文字がチェックされ、目的の大文字と小文字に変換されるため、比較ではすべての文字を再度チェックする必要があります。したがって、より多くのメモリと処理能力を使用します。
Air2 2014年

5
メモリ割り当てのため、これは非常に悪い習慣です。
するThorbjörnLindeijer

これは不必要なメモリ割り当てで非効率なだけでなく、それはまたトルコのテストに不合格です。
ドミトリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.