为什么即使对象被显式初始化为 null,null 检查也会失败
Why does null check fail even though object is explicitly initialized as null
我创建了一个自定义的 abstract class,当然也创建了派生的 classes。
public abstract class AbstractBaseClass
...
public class ChildClass1 : AbstractBaseClass
...
现在,每当我声明 AbstractBaseClass baseClass = null
时,无论在初始化之后进行空检查,它总是失败。
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
}
进行空检查的原因是因为有多个派生的 classes,并且在某些过程中,我确定它是哪种类型(例如使用 switch cases)。当然也有无效的情况,我希望该值是初始化的 null.
这真的很奇怪,我真的很期待 null 检查的结果为真。
发生这种情况的可能原因是什么(所以我可以根据信息添加更多示例代码,因为整个相关代码都很大),以及应该如何一个解决这个?谢谢。
编辑:
此外,调试器值为空。
哦,对了,正如@taffer 提到的,== 对 AbstractBaseClass
来说是过载的。这是该部分和其他相关代码:
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
为 null,您将 return 设置为 false,而忽略 b
也可能是 null
.
你需要做的是 return 如果两者都是 null
,或者如果 a
等于 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
不是,则 .?
运算符将为 return null,而 ??
运算符将为 return false
.
正如 RufusL 在评论中所写,有一个更短的等效代码可以得到相同的结果:
public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
return a?.Equals(b) ?? ReferenceEquals(null, b);
}
如果 a
为空,return 如果 b
也为空则为真。如果 a
不为空,return a.Equals(b)
.
的结果
如果 a
不为空但 b
为空,则您的 Equals
方法应该 return false:
protected bool Equals(AbstractBaseClass other)
{
return other != null
? Equals(this.SomeUniqueProperty, other.SomeUniqueProperty)
: false;
}
我创建了一个自定义的 abstract class,当然也创建了派生的 classes。
public abstract class AbstractBaseClass
...
public class ChildClass1 : AbstractBaseClass
...
现在,每当我声明 AbstractBaseClass baseClass = null
时,无论在初始化之后进行空检查,它总是失败。
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
}
进行空检查的原因是因为有多个派生的 classes,并且在某些过程中,我确定它是哪种类型(例如使用 switch cases)。当然也有无效的情况,我希望该值是初始化的 null.
这真的很奇怪,我真的很期待 null 检查的结果为真。
发生这种情况的可能原因是什么(所以我可以根据信息添加更多示例代码,因为整个相关代码都很大),以及应该如何一个解决这个?谢谢。
编辑:
此外,调试器值为空。
哦,对了,正如@taffer 提到的,== 对 AbstractBaseClass
来说是过载的。这是该部分和其他相关代码:
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
为 null,您将 return 设置为 false,而忽略 b
也可能是 null
.
你需要做的是 return 如果两者都是 null
,或者如果 a
等于 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
不是,则 .?
运算符将为 return null,而 ??
运算符将为 return false
.
正如 RufusL 在评论中所写,有一个更短的等效代码可以得到相同的结果:
public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
return a?.Equals(b) ?? ReferenceEquals(null, b);
}
如果 a
为空,return 如果 b
也为空则为真。如果 a
不为空,return a.Equals(b)
.
如果 a
不为空但 b
为空,则您的 Equals
方法应该 return false:
protected bool Equals(AbstractBaseClass other)
{
return other != null
? Equals(this.SomeUniqueProperty, other.SomeUniqueProperty)
: false;
}