为什么在与null比较时要转换为对象?

17

在浏览MSDN关于Equals重写的文档时,有一点引起了我的注意。

这个页面的示例中,进行比较时进行了一些空值检查,并将对象转换为System.Object类型:

public override bool Equals(System.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);
}

有没有使用这种转换方式的特定原因,还是只是在这个例子中遗忘了一些“无用”的代码?

5个回答

15

某种类型可以重载 "==" 运算符。将其转换为对象可以确保使用原始定义。


15

就像其他人说的一样,类型可能会覆盖==操作符。因此,将其转换为Object相当于if (Object.ReferenceEquals(p, null)) { ... }


4
+1使用ReferenceEquals比将对象强制转换为object更清晰明了。 - Justin
使用ReferenceEquals可以更清晰地表达意图。 - Curt Nichols

7
我认为将其转换为System.Object类型可以避免TwoDPoint可能存在的任何运算符重载。

1

这个转换操作符很可能是为了避免与重载的 == 操作符混淆。想象一下,如果没有这个转换操作符而且 == 操作符被重载了。现在 p == null 这行代码有可能会绑定到 == 操作符上。许多实现 == 操作符的方法只是将其委托给重写的 Equals 方法。这很容易导致堆栈溢出的情况。

public static bool operator==(TwoDPoint left, TwoDPoint right) {
  return left.Equals(right);
}

public override bool Equals(System.Object obj) {
    ...
    TwoDPoint p = obj as TwoDPoint;
    if ( p == null ) {  // Stack overflow!!!
        return false;
    }

    ...
}

通过将其转换为Object,作者确保会发生一个简单的引用检查以检查null(这正是预期的)。

0

这可能是一个更大样品的一部分,其中 == 运算符被重载了。在这种情况下,如果作为 == 定义的一部分调用了 TwoDPoint.Equals(object),使用 obj == null 可能会导致 StackOverflow。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接