Bagaimana String.Equals (a, b) tidak menghasilkan StackOverflowException?

159

Saat memeriksa String ==operator, saya perhatikan ada panggilan String.Equals(string a, string b), artinya hanya jalan-jalan.

Meneliti String.Equals(string a, string b)metode ini, saya melihat bahwa ia melakukan pemeriksaan kesetaraan menggunakan ==operator. Bagaimana ini benar-benar berfungsi dan tidak menyebabkan StackOverflowExceptionketika melakukan sesuatu seperti "x" == "x"atau "x" == "y"?

Pembaruan : Saya memberi tahu JetBrains dan mereka menjadikannya prioritas penting untuk dotPeek. https://youtrack.jetbrains.com/issue/DOTP-6789

Saya juga menambahkan masalah pada repo GitHub ILSpy.

Kesetaraan String

Dustin Davis
sumber
Gratis NET Reflector (v6) menampilkannya "salah" di C # (yaitu hanya menunjukkan a == b), tetapi benar dalam VB.NET: a Is b.
Mark Hurd

Jawaban:

217

Dekompiler Anda memiliki bug. Kode sebenarnya tidak memeriksa a == b, memeriksa (Object)a == (Object)b, mem-bypass operator yang kelebihan beban.


sumber
4
@Aravol benar, tetapi sumbernya baru saja dirilis
Dustin Davis
2
Namun kode ini cukup dikaburkan. Sederhana object.ReferenceEquals(a,b)akan jauh lebih jelas ..
Voo
1
@ Voo Saya berpendapat bahwa versi saat ini lebih jelas. Anda tidak perlu tahu apa-apa tentang object.ReferenceEqualsversi pemeran (mis., Bagaimana jika aitu null?), Dan, selama Anda tahu apa itu casting, tentu saja itu tidak dikaburkan.
wchargin
72
"Dekompiler Anda memiliki bug". Menjatuhkan mik.
espinchi
1
@ Voo Tebakan saya: MS mempertimbangkan (Object)a == (Object)bdan Object.ReferenceEquals(a, b)hampir sama-sama dapat dibaca, tetapi tidak akan mengejutkan saya jika Object.ReferenceEquals(a, b)hanya memiliki sedikit peluang untuk tidak mendapatkan inline jika kedalaman inline maksimum tercapai. MS melakukan banyak optimasi mikro, karena sebagian besar loop ketat dalam kode pengguna akhirnya memanggil kode MS.
50

Ini kode asli dari Microsoft. Operator ==yang menerapkan s

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

==panggilan operator String.Equals yang diimplementasikan sebagai:

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);
}

Seperti yang Anda lihat, perbandingan untuk kesetaraan string dilakukan dengan menggunakan if ((Object)a==(Object)b)casting string ke objectdan kemudian melakukan perbandingan. Jadi ini tidak akan memanggil operator kelebihan beban ==di kelas string.

CriketerOnSO
sumber