Why does null check fail even though object is explicitly initialized as null

强颜欢笑 提交于 2021-02-08 10:14:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!