为什么即使对象显式初始化为空,空检查也会失败 [英] Why does null check fail even though object is explicitly initialized as null
问题描述
我创建了一个自定义的抽象类,当然也创建了派生类.
I have created a custom abstract class, which in turn of course derived classes were also created.
public abstract class AbstractBaseClass
...
public class ChildClass1 : AbstractBaseClass
...
现在,每当我声明例如AbstractBaseClass baseClass = null
,并且在此初始化之后进行空值检查时,它总是失败.
Now, whenever I declare for example AbstractBaseClass baseClass = null
, and wherever null checks follow after this initialization, it always fails.
if (baseClass == null)
{
// this block is never reached - condition always evaluates to false
// let's say AbstractBaseClass baseClass = null is at line 10
// even if this condition is at line 11, condition still fails
}
之所以有空检查是因为有多个派生类,并且在某些过程中,我确定它是哪种类型(例如,使用 switch case).当然也有无效的情况,在这种情况下,我希望该值将是初始化的 null.
Reason why there is a null check is because there are multiple derived classes, and on some process, I determine which type would it be (e.g. using switch cases). And of course there are invalid cases, in which I expect that the value would be the initialized null.
这真的很奇怪,我真的希望 null 检查的结果为 true.
This is really weird, and I really am expecting that null check would evaluate to true.
发生这种情况的可能原因是什么(这样我就可以根据信息添加更多示例代码,因为整个相关代码非常大),应该如何解决这个问题?谢谢.
What could be the possible causes why this happens (so that I can add more sample code depending on the info as the whole relevant code is quite big), and how should one fix this? Thank you.
编辑:
此外,调试器值为空.
哦,对了,正如@taffer 所提到的,AbstractBaseClass
的 == 是重载的.这是该部分和其他相关代码:
Oh that's right, as @taffer mentioned, == is overloaded for AbstractBaseClass
. Here is that part and other relevant code:
protected bool Equals(AbstractBaseClass other)
{
return Equals(this.SomeUniqueProperty, other.SomeUniqueProperty);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj))
{
return false;
}
if (ReferenceEquals(this, obj))
{
return true;
}
return obj.GetType() == this.GetType() && this.Equals((AbstractBaseClass)obj);
}
public override int GetHashCode()
{
return (this.SomeUniqueProperty != null ? this.SomeUniqueProperty.GetHashCode() : 0);
}
public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
if (ReferenceEquals(null, a))
{
return false;
}
return !ReferenceEquals(null, b) && a.Equals(b);
}
public static bool operator !=(AbstractBaseClass a, AbstractBaseClass b)
{
return !(a == b);
}
推荐答案
您的 ==
重载是错误的,因为如果 a
为空,您将返回 false,忽略事实上,b
也可以是 null
.
Your ==
overload is wrong, as you are returning false if a
is null, ignoring the fact that b
could also be null
.
如果两者都是 null
,或者 a
等于 b
,你需要做的是返回 true:<罢工>
What you need to do is return true if both are null
, or if a
equals b
:
public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
var isANull = ReferenceEquals(null, a);
var isBNull = ReferenceEquals(null, b)
return (isANull && isBNull) || a?.Equals(b) ?? false;
}
注意:如果 a
为 null 而 b
不是,.?
运算符将返回 null,而 ??
运算符将返回 false
.
Note: In case a
is null but b
is not, the .?
operator will return null, and the ??
operator will return false
.
正如 RufusL 在评论中所写,有一个较短的等效代码来获得相同的结果:
As RufusL wrote in the comments, there's a shorter eqiuvalent code to get the same results:
public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
return a?.Equals(b) ?? ReferenceEquals(null, b);
}
如果 a
为空,如果 b
也为空,则返回 true.如果 a
不为 null,则返回 a.Equals(b)
的结果.
if a
is null, return true if b
is also null. if a
is not null, return the result of a.Equals(b)
.
如果 a
不是 null 但 b
是,你的 Equals
方法应该返回 false:
In case a
is not null but b
is, your Equals
method should return false:
protected bool Equals(AbstractBaseClass other)
{
return other != null
? Equals(this.SomeUniqueProperty, other.SomeUniqueProperty)
: false;
}
这篇关于为什么即使对象显式初始化为空,空检查也会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!