为什么即使对象被显式初始化为 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;
}