2015-09-26 8 views
5

ich auf den Artikel von MSDN Online Suche Guidelines for Overloading Equals() and Operator ==Seltsame Guss in Equals von MSDN bereitgestellt außer Kraft setzen

und ich sah den folgenden Code

public override bool Equals(object obj) 
{ 
    // If parameter is null return false. 
    if (obj == null) 
    { 
     return false; 
    } 

    // If parameter cannot be cast to Point return false. 
    TwoDPoint p = obj as TwoDPoint; 
    if ((System.Object)p == null) 
    { 
     return false; 
    } 

    // Return true if the fields match: 
    return (x == p.x) && (y == p.y); 
} 

das Merkwürdige ist, die Besetzung in der zweiten zu widersprechen, wenn

// If parameter cannot be cast to Point return false. 
TwoDPoint p = obj as TwoDPoint; 
if ((object)p == null) 
{ 
    return false; 
} 

Warum p ist wieder gegossen, um zu widerlegen? Ist es nicht genug, um diese

// If parameter cannot be cast to Point return false. 
TwoDPoint p = obj as TwoDPoint; 
if (p == null) 
{ 
    return false; 
} 

zu schreiben, wenn p nicht zu TwoDPoint gegossen werden kann, dann ist es Wert null sein wird. Ich bin verwirrt, wahrscheinlich verstehe ich nicht etwas trivial ...

EDIT

Noch eine solche Besetzung in der anderen präsentiert wird Equals Methode

public bool Equals(TwoDPoint p) 
{ 
    // If parameter is null return false: 
    if ((object)p == null) 
    { 
     return false; 
    } 
} 

Auch hier ist es genug, um zu überprüfen, nur if(p == null)

+1

Dies ist ein Code Geruch. Sie hätten ReferenceEquals verwenden sollen. – usr

Antwort

7

(object)p == null verwendet den integrierten Operator ==, der in diesem Fall die Referenzgleichheit überprüft. p == null würde einen überladenen operator== für den angegebenen Typ aufrufen. Wenn das überladene operator== in Bezug auf Equals implementiert wird (es ist nicht, in dem Beispiel, das Sie verknüpfen), dann hätten Sie unendliche Rekursion. Selbst wenn es nicht in Bezug auf Equals implementiert wird, würde es immer noch mehr tun, als getan werden muss.

2

Dies ist sicherzustellen, dass der aufgerufene Operator == die Standardimplementierung von Object ist, nicht die benutzerdefinierte. Es ist ein häufiger Fehler, eine ungebundene Rekursion in einem solchen Code einzuführen, indem sich die eigenen Operatoren selbst nennen.

4

Um beide Antworten zu vervollständigen, ist die von Ihnen betrachtete Dokumentation veraltet, wie oben auf der Seite angegeben. Wenn man sich die newer guidelines sucht, gibt es eine Notiz, die genau erklärt, warum das getan wird:

Ein häufiger Fehler bei Überlastungen des Operators == (a == b) zu verwenden, (a == null), oder (b == null), um nach einer Referenzgleichheit zu suchen. Das stattdessen erstellt einen Aufruf an den überladenen Operator ==, was eine unendliche Schleife verursacht. Verwenden Sie ReferenceEquals, oder wenden Sie den Typ auf Object, um die Schleife zu vermeiden.

Grundsätzlich damit gleich object.ReferenceEquals zu verwenden, das ist, was der Code tatsächlich versucht, zu tun:

TwoDPoint p = obj as TwoDPoint; 
if (object.ReferenceEquals(p, null)) 
{ 
    return false; 
} 
Verwandte Themen