2015-07-20 48 views
6

当重写Equals()法,MSDN recommends this覆盖Equals():当调用base.Equals()时为空比较多余?

class Point: Object { 
    protected int x, y; 

    public Point(int X, int Y) { 
     this.x = X; 
     this.y = Y; 
    } 

    public override bool Equals(Object obj) { 

     //Check for null and compare run-time types. 
     if (obj == null || GetType() != obj.GetType()) return false; 

     Point p = (Point)obj; 

     return (x == p.x) && (y == p.y); 
    } 
} 

但是,如果我们知道,子类直接从Object继承,然后如下相当于?注意​​电话:

class Point: Object { 
    protected int x, y; 

    public Point(int X, int Y) { 
     this.x = X; 
     this.y = Y; 
    } 

    public override bool Equals(Object obj) { 

     if (!base.Equals(obj) || GetType() != obj.GetType()) return false; 

     Point p = (Point)obj; 

     return (x == p.x) && (y == p.y); 
    } 
} 
+0

不,因为'!base.Equals(obj)'将返回true,导致Equals方法返回'false',如果它们不是完全相同的对象。如果他们是同一个对象,那么您的支票的其余部分将保证成功。它基本上会让你的重写无所事事。 – Rob

+0

@Rob - 如果'!base.Equals(obj)'返回true,那么你*想*返回false。 –

+0

'base.Equals(obj)'将检查当前对象和'obj'是否是*确切*相同的对象。也就是说,它们是指向内存中完全相同的对象的指针。如果它们是不同的对象,您的等于将立即返回false。如果它们*是*相同的对象,那么'GetType()== obj.GetType()'和'(x == px)&&(y == py)'都保证返回'true' – Rob

回答

5

如果this引用null你是正确的,该检查可以(但似乎并没有得到保证)多余的,因为可以在RuntimeHelpers.Equals实施this answer报价中可以看出。

但是,!base.Equals(obj)检查将打破您的Equals。当参考文献不是null-!base.Equals也将产生true对于任何不同的参考文献不仅对于null值。

的情况下,当它出错是例如:

Point x = new Point(1,2); 
Point y = new Point(1,2); 

Console.WriteLine(x.Equals(y)); // will print 'False' 

即使xy是你的业务逻辑方面的平等的,它们是不同的对象,因此base.Equal回报false

+0

哦!现在我懂了。这是一个非常重要的语义错误! – kdbanman

+0

在C#中'this'是否为空,除非是手写IL?我不认为它可以,但我可能是错的 – Rob

+1

@BartoszKP究竟如何?你不能通过'MethodInfo.Invoke'在null对象上调用成员方法,而且你绝对不能'MyTest t = null; t.Equals(空)'。 – Rob

相关问题