开发者

Cast to object before null check in overriding Equals [duplicate]

This question already has answers here: In the msdn guidance on Equals override, why the cast to object in the null check? (3 answers) Closed 5 years ago.

Just reading the msdn article on overriding equality operators here

The following snippet confuses me...

// 开发者_运维技巧If parameter cannot be cast to Point return false.
TwoDPoint p = obj as TwoDPoint;
if ((System.Object)p == null) // <-- wtf?
{
    return false;
}

Why is there a cast to Object here to perform the null comparison?


Operators apply through static analysis (and overloads), not virtual methods (overrides). With the cast, it is doing a reference equality check. Without the cast, it can run the TwoDPoint operator. I guess this is to avoid problems when an operator is added.

Personally, though, I'd do a reference check explicitly with ReferenceEquals.


No! if you don't do that, the runtime will start a recursive call to the equality operator you are just in which results in infinite recursion and, consequently, a stack overflow.


To force it to use the Equals method of Object rather than its own overloaded version... just a guess...


This is not useless. Without that cast the == operator being overloaded would be called recursively...


the below is the line that does the cast

TwoDPoint p = obj as TwoDPoint

the difference with the "normal" cast is that using "As" it doesn't raise an exception if the object is not "castable". In this case if "p" is not a TwoDPoint Type is not gonna raise an exception (cast not valid) but return null.

if ((System.Object)p == null) // <-- wtf? 
{ 
    return false; 
} 

this code check if the cast went fine if not p should be null for the reason above


Note that this is the VS 2005 documentation. I guess the folks who write the documentation also had the same question and couldn't come up with a good answer; the example was changed for VS 2008. Here is the current version:

public bool Equals(TwoDPoint p)
{
    // If parameter is null, return false.
    if (Object.ReferenceEquals(p, null))
    {
        return false;
    }

    // Optimization for a common success case.
    if (Object.ReferenceEquals(this, p))
    {
        return true;
    }

    // If run-time types are not exactly the same, return false.
    if (this.GetType() != p.GetType())
        return false;

    // Return true if the fields match.
    // Note that the base class is not invoked because it is
    // System.Object, which defines Equals as reference equality.
    return (X == p.X) && (Y == p.Y);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜