2015-07-20 13 views
6

Quando l'override del metodo Equals(), il MSDN recommends this:Overriding Equals(): il confronto null è ridondante quando si chiama base.Equals()?

class Point: Object { 
    protected int x, y; 

    public Point(int X, int Y) { 
     this.x = X; 
     this.y = Y; 
    } 

    public override bool Equals(Object obj) { 

     //Check for null and compare run-time types. 
     if (obj == null || GetType() != obj.GetType()) return false; 

     Point p = (Point)obj; 

     return (x == p.x) && (y == p.y); 
    } 
} 

Ma se sappiamo che la sottoclasse eredita direttamente da Object, quindi è il seguente equivalente? Si noti la !base.Equals() chiamata:

class Point: Object { 
    protected int x, y; 

    public Point(int X, int Y) { 
     this.x = X; 
     this.y = Y; 
    } 

    public override bool Equals(Object obj) { 

     if (!base.Equals(obj) || GetType() != obj.GetType()) return false; 

     Point p = (Point)obj; 

     return (x == p.x) && (y == p.y); 
    } 
} 
+0

No, poiché '! Base.Equals (obj)' restituirà 'true', facendo sì che il metodo Equals restituisca' false' se non sono esattamente lo stesso oggetto. Se sono lo stesso oggetto, allora il resto del tuo assegno è garantito per avere successo. In pratica farà in modo che il tuo override non faccia nulla. – Rob

+0

@Rob - se '! Base.Equaliti (obj)' restituisce true, quindi * si desidera * per restituire false. –

+0

'base.Equals (obj)' controllerà se l'oggetto corrente e 'obj' sono lo stesso * esatto * oggetto. Cioè, che sono puntatori allo stesso identico oggetto in memoria. Se sono oggetti diversi, i tuoi pari torneranno immediatamente falsi. Se * sono * lo stesso oggetto, allora 'GetType() == obj.GetType()' e '(x == px) && (y == py)' sono entrambi garantiti per restituire 'true' – Rob

risposta

5

In caso this riferimento è null hai ragione, che il controllo può essere (ma non sembra essere garantita) superflua, come si può vedere in RuntimeHelpers.Equals implementazione citato in this answer.

Tuttavia, il controllo !base.Equals(obj) interromperà il numero Equals. Se i riferimenti non sono null - !base.Equals, restituirà true per qualsiasi altro riferimenti non solo per i valori null.

Lo scenario in cui le cose vanno male è per esempio:

Point x = new Point(1,2); 
Point y = new Point(1,2); 

Console.WriteLine(x.Equals(y)); // will print 'False' 

Anche se x e y sono uguali in termini della logica di business, sono oggetti diversi in modo base.Equal restituisce false.

+0

Oh! Ora capisco. Questo è un errore semantico piuttosto significativo! – kdbanman

+0

C'è mai un caso in cui 'this' è nullo in C# tranne quando è scritto a mano IL? Non penso che possa essere, ma potrei sbagliarmi – Rob

+1

@BartoszKP Come, esattamente? Non puoi invocare un metodo membro su un oggetto nullo tramite 'MethodInfo.Invoke', e sicuramente non puoi fare' MyTest t = null; t.Equals (null) '. – Rob

Problemi correlati