为什么即使对象被显式初始化为null,null检查仍会失败

时间:2019-03-19 08:31:55

标签: c# inheritance null abstract-class null-check

我创建了一个自定义的抽象类,该类当然也创建了派生类。

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
}

之所以为什么要执行null检查是因为存在多个派生类,并且在某些过程中,我确定它是哪种类型(例如,使用切换用例)。当然,在某些情况下,我希望该值将被初始化为 null

这真的很奇怪,我真的希望null检查的结果为true。

发生这种情况的可能原因是什么(,以便我可以根据信息添加更多示例代码,因为整个相关代码都很大),并且应该如何解决?谢谢。

编辑

此外,调试器值为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);
    }

1 个答案:

答案 0 :(得分:3)

您的==重载是错误的,因为如果a为空,则返回false,而忽略了b也可能是null的事实。

如果两者均为nulla等于b,则需要返回true:

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,则.?运算符将返回null,而??运算符将返回false

正如RufusL在评论中所写,有一个较短的等价代码可以得到相同的结果:

public static bool operator ==(AbstractBaseClass a, AbstractBaseClass b)
{
    return a?.Equals(b) ?? ReferenceEquals(null, b);
}

如果a为空,如果b也为空,则返回true。如果a不为null,则返回a.Equals(b)的结果。

如果a不是null但b是null,则您的Equals方法应返回false:

protected bool Equals(AbstractBaseClass other)
{
    return other != null 
        ? Equals(this.SomeUniqueProperty, other.SomeUniqueProperty) 
        : false;
}