覆盖 Equals():调用 base.Equals() 时空值比较是否多余?
Overriding Equals(): is null comparison redundant when calling base.Equals()?
重写 Equals()
方法时,MSDN recommends this:
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
,那么是不是等价于下面的?注意 !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) {
if (!base.Equals(obj) || GetType() != obj.GetType()) return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
}
如果 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'
尽管 x
和 y
就您的业务逻辑而言是相同的,但它们是不同的对象,因此 base.Equal
returns false
.
重写 Equals()
方法时,MSDN recommends this:
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
,那么是不是等价于下面的?注意 !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) {
if (!base.Equals(obj) || GetType() != obj.GetType()) return false;
Point p = (Point)obj;
return (x == p.x) && (y == p.y);
}
}
如果 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'
尽管 x
和 y
就您的业务逻辑而言是相同的,但它们是不同的对象,因此 base.Equal
returns false
.