为什么即使对象显式初始化为空,空检查也会失败 [英] Why does null check fail even though object is explicitly initialized as null

查看:61
本文介绍了为什么即使对象显式初始化为空,空检查也会失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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
...

现在,每当我声明例如AbstractBaseClass baseClass = null,并且在此初始化之后进行空值检查时,它总是失败.

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
}

之所以有空检查是因为有多个派生类,并且在某些过程中,我确定它是哪种类型(例如,使用 switch case).当然也有无效的情况,在这种情况下,我希望该值将是初始化的 null.

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.

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

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.

编辑:

此外,调试器值为空.

哦,对了,正如@taffer 所提到的,AbstractBaseClass 的 == 是重载的.这是该部分和其他相关代码:

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);
    }

推荐答案

您的 == 重载是错误的,因为如果 a 为空,您将返回 false,忽略事实上,b 也可以是 null.

Your == overload is wrong, as you are returning false if a is null, ignoring the fact that b could also be null.

如果两者都是 null,或者 a 等于 b,你需要做的是返回 true:<罢工>

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;
}

注意:如果 a 为 null 而 b 不是,.? 运算符将返回 null,而 ?? 运算符将返回 false.

Note: In case a is null but b is not, the .? operator will return null, and the ?? operator will return false.

正如 RufusL 在评论中所写,有一个较短的等效代码来获得相同的结果:

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);
}

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

if a is null, return true if b is also null. if a is not null, return the result of a.Equals(b).

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

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;
}

这篇关于为什么即使对象显式初始化为空,空检查也会失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆