String.Equals (a, b) nasıl StackOverflowException oluşturmaz?


159

String ==Operatörü incelerken, aradığını fark ettim String.Equals(string a, string b), yani sadece bir geçiş.

String.Equals(string a, string b)Yöntemi inceleyerek, ==operatörü kullanarak bir eşitlik kontrolü yaptığını görüyorum . Bu nasıl çalışıyor ve ya da StackOverflowExceptionböyle bir şey yaparken bir zamana neden olmuyor ?"x" == "x""x" == "y"

Güncelleme : JetBrains'e haber verdim ve dotPeek için kritik bir öncelik haline getirdiler. https://youtrack.jetbrains.com/issue/DOTP-6789

ILSpy'ın GitHub repo'suna da bir sorun ekledim.

Dize Eşitliği


C # (bunu sadece gösterileri yani "yanlış" ücretsiz .NET Reflektör (v6) görüntüler a == b), ancak doğru VB.NET içinde: a Is b.
Mark Hurd

Yanıtlar:


217

Decompiler'ınızda bir hata var. Gerçek kod aşırı yüklenmiş operatörü atlayarak kontrol etmez a == b, kontrol eder (Object)a == (Object)b.


4
@Aravol doğru, ancak kaynak henüz yeni yayınlandı
Dustin Davis

2
Yine de her durumda oldukça gizli kod. Basit bir object.ReferenceEquals(a,b)çok daha açık olurdu ..
Voo

1
@Voo Mevcut sürümün daha net olduğunu iddia ediyorum. Sen hakkında hiçbir şey bilmek gerekmez object.ReferenceEquals(ne olur örneğin dökme sürümüyle aolduğu nullsürece döküm ne bildiği gibi, kesinlikle Karartılmış değil?), Vb.
wchargin

72
Msgstr "Decompiler'ınızda hata var". Mikrofonu düşürür.
espinchi

1
@Voo Benim tahminim: MS düşünün (Object)a == (Object)bve Object.ReferenceEquals(a, b)yaklaşık eşit okunabilir, ama eğer bana sürpriz olmaz Object.ReferenceEquals(a, b)sadece azami satır içi derinliği ulaşılırsa inlined almıyorum hafif bir şansı vardır. MS, çok sayıda mikro optimizasyon yapar, çünkü kullanıcı kodundaki çoğu sıkı döngü MS kodunu çağırır.

50

İşte Microsoft'un gerçek kodu. Operatör ==olan bir uygulamaya s

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

aşağıdaki gibi uygulanan operatör ==çağrıları :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);
}

Gördüğünüz gibi, dize eşitliği karşılaştırması, dizeyi if ((Object)a==(Object)b)döküm objectyaparak ve sonra karşılaştırmayı yaparak yapılır. Bu nedenle ==, string sınıfında aşırı yüklenmiş operatörü çağırmaz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.