问题
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
...
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
}
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.
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.
EDIT:
Also, debugger value is null.
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);
}
回答1:
Your ==
overload is wrong, as you are returning false if a
is null, ignoring the fact that b
could also be null
.
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;
}
Note: In case a
is null but b
is not, the .?
operator will return null, and the ??
operator will return false
.
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);
}
if a
is null, return true if b
is also null. if a
is not null, return the result of a.Equals(b)
.
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;
}
来源:https://stackoverflow.com/questions/55236501/why-does-null-check-fail-even-though-object-is-explicitly-initialized-as-null