2015-09-26 83 views
5
提供

我在看从MSDN Guidelines for Overloading Equals() and Operator ==中值为奇怪铸覆盖由MSDN

的文章,我看到了下面的代码

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); 
} 

奇怪的是在第二,如果

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

为什么p再次铸造对象?是不是足够写这

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

如果p不能铸造TwoDPoint,那么它的值将为空。我百思不得其解,大概我不明白一些小事...

编辑

另外一个此类铸件呈现在其他equals方法

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

这里再次这足以检查只有if(p == null)

+1

这是一个代码味道。他们应该使用ReferenceEquals。 – usr

回答

7

(object)p == null使用内置==运算符,在这种情况下检查引用相等性。 p == null将针对指定的类型调用超载的operator==。如果超载operator==将按照Equals(不是,在您链接的示例中)执行,那么您将拥有无限递归。即使它没有按照Equals执行,它仍然会做得比需要做的更多。

2

这是为了确保调用==操作符是Object的默认实现,而不是用户定义的实现。通过让自己的操作员自己调用自己,在代码中引入无限递归是一个常见的错误。

4

为了完成这两个答案,您查看的文档已过时,如页面顶部所述。如果你看一下newer guidelines,还有一张纸条,上面确切解释为什么正在做:

在运营商的重载一个常见的错误==是使用(A == B),(A == null)或(b == null)来检查引用是否相等。 而不是 创建对重载运算符==的调用,从而导致无限循环 。使用ReferenceEquals或将类型转换为Object,以避免 循环。

基本上,这样做等于用object.ReferenceEquals,这是什么代码实际上是试图做:

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