String.Equals(a、b)がStackOverflowExceptionを生成しないのはなぜですか?


159

String ==オペレーターを調べているとString.Equals(string a, string b)、それがを呼び出していることに気付きました。

String.Equals(string a, string b)メソッドを調べると、==演算子を使用して等価チェックを実行していることがわかります。これは実際にどのように機能しており、またはのStackOverflowExceptionようなことをしたときにを引き起こしていません"x" == "x""x" == "y"

更新:私はJetBrainsに知らせ、dotPeekの重要な優先事項にしました。https://youtrack.jetbrains.com/issue/DOTP-6789

ILSpyのGitHubリポジトリにも問題を追加しました。

文字列の平等


無料の.NET Reflector(v6)はC#で「間違っている」と表示します(つまり、を表示するだけですa == b)が、VB.NETでは正しいですa Is b
Mark Hurd、2014

回答:


217

デコンパイラにバグがあります。実際のコードはチェックせずa == b、チェック(Object)a == (Object)bし、オーバーロードされた演算子をバイパスします。


4
@Aravolは真実ですが、ソースは最近リリースされたばかりです
ダスティンデイビス

2
とにかく、それはかなり難読化されたコードです。シンプルがobject.ReferenceEquals(a,b)より明確になります...
VOO

1
@Voo私は現在のバージョンがより明確であると主張します。あなたはについて何か知っている必要はありませんobject.ReferenceEquals(場合は何例えば、キャスト版でaあるにnull限り、あなたはキャストが何であるかを知っているように、それは確かに難読化されていない、?)、と。
wchargin 14

72
「デコンパイラにはバグがあります」。マイクを落とします。
espinchi 2014

1
@Voo私の推測:MSが考える(Object)a == (Object)bObject.ReferenceEquals(a, b)について平等に読めるが、あれば、それは私は驚かないだろうObject.ReferenceEquals(a, b)だけで、最大のインライン深さに達した場合、インライン化ばかりではないのわずかなチャンスを持っています。ユーザーコードのほとんどのタイトループは最終的にMSコードを呼び出すため、MSは多くのマイクロ最適化を行います。

50

これがマイクロソフトの実際のコードです。オペレータが==されて実装

public static bool operator == (String a, String b) {
   return String.Equals(a, b);
}

次の==ようString.Equals に実装されるオペレーター呼び出し:

public static bool Equals(String a, String b) {
    if ((Object)a==(Object)b) {
        return true;
    }

    if ((Object)a==null || (Object)b==null) {
        return false;
    }

    if (a.Length != b.Length)
        return false;

    return EqualsHelper(a, b);
}

ご覧のとおり、文字列が等しいかどうかの比較は、文字列をにif ((Object)a==(Object)b)キャストしobjectてから比較を行うことで行われます。したがって、これは==文字列クラスのオーバーロードされた演算子を呼び出しません。

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