web-dev-qa-db-ja.com

String.Equalsがfalseを返すのはなぜですか?

拇印を比較する証明書を見つけようとする次のC#コード(使用しているライブラリから)があります。次のコードでは、_mycert.Thumbprint_とcertificateThumbprintの両方が文字列であることに注意してください。

_var certificateThumbprint = AppSettings.CertificateThumbprint;

var cert =
    myStore.Certificates.OfType<X509Certificate2>().FirstOrDefault(
      mycert => 
      mycert.Thumbprint != null && mycert.Thumbprint.Equals(certificateThumbprint)
      );
_

文字列が等しい場合でもmycert.Thumbprint.Equals(certificateThumbprint)falseであるため、拇印のある証明書を見つけることができません。 _mycert.Thumbprint == certificateThumbprint_もfalseを返し、mycert.Thumbprint.CompareTo(certificateThumbprint)は0を返します。

enter image description here

明らかな何かが欠けているかもしれませんが、Equalsメソッドが失敗する理由がわかりません。アイデア?

23
Marius Bancila

CompareToは特定の文字を無視します:

static void Main(string[] args)
{
    var a = "asdas"+(char)847;//add a hidden character
    var b = "asdas";
    Console.WriteLine(a.Equals(b)); //false
    Console.WriteLine(a.CompareTo(b)); //0
    Console.WriteLine(a.Length); //6
    Console.WriteLine(b.Length); //5

   //watch window shows both a and b as "asdas"
}

(ここで、aに追加される文字はU+034F、Grapheme Joinerの組み合わせ。)

Debug mode

したがって、CompareToの結果は、Equalsのバグを示す良い指標ではありません。問題の最も可能性の高い理由は、隠された文字です。あなたは確かに長さをチェックすることができます。

詳細については、 this を参照してください。

21
brz

タイプStringComparisonのパラメーターを受け入れるString.Equalsのオーバーロードを使用してみることをお勧めします。

例:

myCert.Thumbprint.Equals(certificateThumbprint, StringComparison.[SomeEnumeration])


ここで、[SomeEnumeration]は次の列挙定数のいずれかに置き換えられます。

 - CurrentCulture
 - CurrentCultureIgnoreCase
 - InvariantCulture
 - InvariantCultureIgnoreCase
 - Ordinal
 - OrdinalIgnoreCase


見つかったMSDNドキュメントを参照してくださいここ。 enter image description here

2
AperioOculus

データベースにデータを挿入すると、"question"のようなスペースが格納されることがあります。そして、それを"question"と比較しようとすると、falseが返されます。したがって、私の提案は、データベースの値を確認するか、Trim()メソッドを使用してください。

あなたの場合、試してみてください:mycert.Thumbprint!= null && mycert.Thumbprint.trim()。equals(certificateThumbprint.trim())

レコードがあればtrueを返すと思います。

0
Subhash