在null检查覆盖Equals之前转换为对象

时间:2010-11-05 12:01:38

标签: c# casting null equality

阅读有关重写等号运算符here

的msdn文章

以下代码段让我感到困惑......

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

为什么要在Object进行投射以执行null比较?

6 个答案:

答案 0 :(得分:9)

运算符通过静态分析(和重载)应用,而不是虚拟方法(覆盖)。使用强制转换,它正在进行引用相等性检查。没有强制转换,它可以运行TwoDPoint运算符。我想这是为了避免在添加运算符时出现问题。

但就个人而言,我会明确地使用ReferenceEquals进行参考检查。

答案 1 :(得分:3)

没有!如果你不这样做,运行时将启动对你刚才所在的相等运算符的递归调用,这会导致无限递归,从而导致堆栈溢出。

答案 2 :(得分:0)

强制它使用Object的Equals方法而不是它自己的重载版本...只是一个猜测......

答案 3 :(得分:0)

这不是没用的。如果没有那个强制转换,那么重载的==运算符将被递归调用...

答案 4 :(得分:0)

以下是执行施法的行

TwoDPoint p = obj as TwoDPoint

与“正常”强制转换的区别在于,如果对象不是“可投射”,则使用“As”不会引发异常。在这种情况下,如果“p”不是TwoDPoint类型不会引发异常(强制转换无效)但返回null。

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

此代码检查演员表是否正常,如果上述原因不是p应为null

答案 5 :(得分:0)

请注意,这是VS 2005文档。我想那些撰写文档的人也有同样的问题,无法得出一个好的答案; VS 2008的示例已更改。以下是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);
}