VB.NETでも等値演算子で文字列を比較したい
言い訳
もしかしたら生粋のVBプログラマなら常識的なことなのかもしれませんが、等値演算子『=』(で呼び方あってますよね?)で文字列を比較するときに空文字とNothingの比較でつまずいたのでそれのメモ。
なんで違う?
以下のC#とVB.NETのコードを見て、実行結果を同じと思いますか? それとも違うと思いますか?
string str1 = ""; string str2 = null; // false Console.WriteLine(str1 == str2); // false Console.WriteLine(str1.Equals(str2));
Dim str1 As String = "" Dim str2 As String = Nothing ' True Console.WriteLine(str1 = str2) ' False Console.WriteLine(str1.Equals(str2))
コメントで答えを書いちゃっているんですけど結果が違うんです。
等値演算子を使ってる方はC#は期待通りの答えを返してくれるのになんでVB.NETはNothing
と""
であからさまに違うものを等しいと評価しているでしょうか。どちらも演算子オーバーロードされているメソッドを呼び出してるんじゃないんですか?
意味ワカンネ。
出、出〜www 即IL逆変換奴〜www
まぁ、逆アセンブラにでも突っ込めばそれぞれ何のメソッドを呼び出しているか分かるでしょう。 そういう事でぶち込んでみたところ、それぞれ違うメソッドを呼び出していることが分かりました。
C#の方はSystem.String::op_Equality
、VB.NETはMicrosoft.VisualBasic.CompilerServices.Operators::CompareString
を呼び出しているようです。
Operators::CompareString
?
知らない子ですね。
Operators.CompareString メソッド (String, String, Boolean) (Microsoft.VisualBasic.CompilerServices)
説明を読む限り、VB.NETのコンパイルオプションのOption Compare
を実現するためにコンパイル時にこいつに置き換えているみたいです。
Option Compare
の値によって比較方法を変えるためにこいつに置き換えてからbinary
かtext
かで第三引数の値を当てはめているみたいです。
アセンブリを読む限り、『=』で比較されたらCompareString
で比較して返り値を0
と等しいかを比較し、その値を返しているみたいです。
んで、CompareString
は""
とNothing
を同じ値と見なしていると。
何ででしょう? レガシーVBとの互換性の為ですか?
ドキュメントを大切に
あと、この記事を書くために調べて気が付いたのですが、この事はフツーにmsdnの注意書きに書いてありました。
String.Equality 演算子 (String, String) (System)
この件から私が得る教訓は、VB.NETで不可解な事があってもいきなり検証コードを書き始めたり逆アセンブルを行う前に関連するであろうmsdnドキュメントには一通り目を通しておくべきだと言うことだ。