2010-08-04 158 views
17

在Equals覆盖中浏览MSDN文档时,有一点引起了我的注意。为什么要比较null时将对象转换为对象?

this specific page的例子,一些空的检查是由,和做比较,当对象被浇铸成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); 
} 

是否有使用该投一个具体的理由,或这只是在这个例子中被遗忘的一些“无用的”代码?

回答

15

类型可能会重载==运算符。转换为对象可确保使用原始定义。

+0

因此使得exmaple代码安全复制和粘贴。 – 2010-08-04 15:35:13

7

我相信铸造到System.Object会绕过任何运算符重载TwoDPoint可能有。

0

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

15

正如其他人所说,类型可能会覆盖==运算符。因此,铸造到Object相当于if (Object.ReferenceEquals(p, null)) { ... }

+4

+1使用ReferenceEquals对我来说比对对象更清晰 – Justin 2010-08-04 15:33:07

+0

+1通过使用ReferenceEquals可以更清晰地显示其意图。 – 2010-08-04 16:41:47

1

它可能存在以避免与重载的==运算符混淆。想象一下,如果演员不存在,并且==运算符被超载。现在p == null行可能会绑定到运算符==。 operator ==的许多实现只是推迟重写的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会发生(这是何意)。