In che modo String.Equals (a, b) non produce StackOverflowException?


159

Durante l'esame String ==dell'operatore, ho notato che chiama String.Equals(string a, string b), il che significa che è solo un pass-through.

Esaminando il String.Equals(string a, string b)metodo, vedo che esegue un controllo di uguaglianza utilizzando l' ==operatore. In che modo funziona davvero e non causa problemi StackOverflowExceptionquando si fa qualcosa di simile "x" == "x"o "x" == "y"?

Aggiornamento : ho informato JetBrains e lo hanno reso una priorità fondamentale per dotPeek. https://youtrack.jetbrains.com/issue/DOTP-6789

Ho anche aggiunto un problema sul repository GitHub di ILSpy.

Uguaglianza di stringa


Le .NET Reflector (v6) free visualizza lo "sbagliato" in C # (cioè solo spettacoli a == b), ma corretta in VB.NET: a Is b.
Mark Hurd,

Risposte:


217

Il tuo decompilatore ha un bug. Il vero codice non controlla a == b, controlla (Object)a == (Object)b, bypassando l'operatore sovraccarico.


4
@Aravol vero, ma la fonte è stata rilasciata solo di recente
Dustin Davis il

2
È comunque un codice piuttosto offuscato. Un semplice object.ReferenceEquals(a,b)sarebbe molto più chiaro ..
Voo

1
@Voo direi che la versione attuale è più chiara. Non è necessario sapere nulla object.ReferenceEqualsdella versione del cast (ad esempio, what if ais null?) E, fintanto che sai cos'è il casting, non è certamente offuscato.
wchargin,

72
"Il tuo decompilatore ha un bug". Rilascia il microfono.
espinchi,

1
@Voo La mia ipotesi: la SM considera (Object)a == (Object)be Object.ReferenceEquals(a, b)quasi ugualmente leggibile, ma non mi sorprenderebbe se avesse Object.ReferenceEquals(a, b)solo una leggera possibilità di non essere allineata se si raggiungesse la massima profondità in linea. La MS esegue molte micro-ottimizzazioni, poiché la maggior parte dei cicli stretti nel codice utente finiscono per chiamare il codice MS.

50

Ecco il vero codice di Microsoft. L'operatore ==è implementato a s

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

l'operatore ==chiama String.Equals implementato come:

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

Come vedi, il confronto per l'uguaglianza delle stringhe viene eseguito usando il if ((Object)a==(Object)b)cast della stringa objecte quindi facendo il confronto. Quindi questo non chiamerà l'operatore sovraccarico ==nella classe stringa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.