以下は大文字と小文字が区別されることを知っています。
if (StringA == StringB) {
では、2つの文字列を無差別に比較する演算子はありますか?
~=
するparallel ==
を大文字と小文字を区別しないバージョンとして定義するとします。
以下は大文字と小文字が区別されることを知っています。
if (StringA == StringB) {
では、2つの文字列を無差別に比較する演算子はありますか?
~=
するparallel ==
を大文字と小文字を区別しないバージョンとして定義するとします。
回答:
これを試して:
string.Equals(a, b, StringComparison.CurrentCultureIgnoreCase);
if A$=B$ then goto 10
」を使用できる時代は過ぎ去った
文字の大文字と小文字を無視して2つの文字列を比較する最良の方法は、序数を無視する大文字と小文字の文字列比較を指定するString.Equals静的メソッドを使用することです。これは最速の方法でもあり、文字列を小文字または大文字に変換してから比較するよりもはるかに高速です。
私は両方のアプローチのパフォーマンスをテストし、通常の無視の場合の文字列比較は9倍以上高速でした!また、文字列を小文字または大文字に変換するよりも信頼性が高くなります(トルコ語のi問題を確認してください)。したがって、常にString.Equalsメソッドを使用して、文字列が等しいかどうかを比較します。
String.Equals(string1, string2, StringComparison.OrdinalIgnoreCase);
カルチャ固有の文字列比較を実行する場合は、次のコードを使用できます。
String.Equals(string1, string2, StringComparison.CurrentCultureIgnoreCase);
2番目の例では、現在のカルチャの文字列比較ロジックを使用するため、最初の例の「通常の大文字と小文字を区別しない」比較よりも遅くなることに注意してください。最大のパフォーマンスが得られたら、「通常の大文字と小文字を区別しない」比較を使用します。
詳細については、ブログの全文をお読みください。
ToLower
またはToLowerInvariant
、比較を実行するためだけにメモリを作成します。Unicodeに新しい文字セットが追加されると、失敗する可能性があります。ToUpper
特にトルコ語の「i」のために失敗します。ToLower
同様の理由で将来失敗しない理由はありません。
ToLower
またはToLowerInvariant
メソッドを使用することはお勧めしませんString.Equals
。メソッドがいかに効率的かを示したかっただけです。
StringComparer
静的クラスには、必要に応じて大文字と小文字を区別するタイプの比較子を返すプロパティがいくつかあります。
たとえば、あなたは呼び出すことができます
StringComparer.CurrentCultureIgnoreCase.Equals(string1, string2)
または
StringComparer.CurrentCultureIgnoreCase.Compare(string1, string2)
引数を取るオーバーロードstring.Equals
やstring.Compare
オーバーロードよりも少しクリーンですStringComparison
。
System.Collections.CaseInsensitiveComparer
または
System.StringComparer.OrdinalIgnoreCase
オペレーター?いいえ、ただし、文字列の比較で大文字と小文字を区別しないようにカルチャを変更できると思います。
// you'll want to change this...
System.Threading.Thread.CurrentThread.CurrentCulture
// and you'll want to custimize this
System.Globalization.CultureInfo.CompareInfo
これにより、equals演算子による文字列の比較方法が変わると確信しています。
ここで構文を簡略化するアイデア:
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
IgnoreCase
vs IgnoreCaseString
)あいまいです(Javaは暗黙的なボックス化解除と暗黙的なボックス化を選択するため、Javaでこれを暗黙的にキャストして文字列に戻すことはできないと思います)。そして、これにより、2つの新しいオブジェクトのメモリオーバーヘッドが作成され、比較ごとにコールツリーが実行され、表示された使用例のいくつかのネストされたメソッド呼び出しにジャンプします。とはいえ、ほとんどの場合、パフォーマンスはおそらく十分です。
私はこれらの比較方法の最後に入力することに慣れています: , StringComparison.
だから私は拡張を行いました。
namespace System
{ public static class StringExtension
{
public static bool Equals(this string thisString, string compareString,
StringComparison stringComparison)
{
return string.Equals(thisString, compareString, stringComparison);
}
}
}
thisString
extを呼び出す前にnullを確認する必要があることに注意してください。
if (StringA.ToUpperInvariant() == StringB.ToUpperInvariant()) {
人々は、ToUpperInvariant()がToLowerInvariant()よりも速いと報告しています。
他の答えはここでは完全に有効ですが、どういうわけか入力StringComparison.OrdinalIgnoreCase
してを使用するのにも時間がかかりますString.Compare
。
単純な文字列拡張メソッドをコーディングしました。ブール値を使用して、比較で大文字と小文字を区別するか、区別しないかを指定できます。次の回答を参照してください。