为什么在“ if”语句中使用的猫王运算符不再是布尔代数?

时间:2018-11-30 12:57:28

标签: c#

下面的代码:

class B
{
    public bool FinishedDownloading { get; set; } = false;
};

class A
{
    public B DownloadStream { get; set; }
};

A a = new A();

Console.WriteLine(a.DownloadStream?.FinishedDownloading != false);
Console.WriteLine(a.DownloadStream?.FinishedDownloading == true);

输出:

True
False

a.DownloadStream?.FinishedDownloading != falsetrueDownloadStreamnull时,FinishedDownloadingfalse是什么?!

让我们忘记发生了什么,并专注于结果。

我们知道该语句a.DownloadStream?.FinishedDownloading != false是正确的,因为它不是false,因此在我们的宇宙中,如果某件事为真,那么它应该为真,因为1 == 1,对吧?

那为什么当我们做a.DownloadStream?.FinishedDownloading == true时,结果现在为假?!疯狂。

我想我有点知道这是怎么回事。这是因为,当DownloadStream为null时,无法访问FinishedDownloading布尔值,因此左侧为null,因此C#会“思考”:

  • a.DownloadStream?.FinishedDownloading != false
      

    好,让我们检查一下null值是否不等于布尔“ false”值。嗯,当然不是,所以让我们输出为真。

  • a.DownloadStream?.FinishedDownloading == true
      

    好吧,让我们比较一个空值和一个布尔值“ true”。嗯,那没有任何意义。这不是真的,所以让我们输出false。

有人知道这是真的吗?我觉得这很容易混淆且容易出错。

1 个答案:

答案 0 :(得分:9)

您忘记了Nullable<bool>(也称为bool?)和bool是两种不同的类型,具有不同的可能值列表。

  • bool可以是truefalse
  • bool?可以是truefalsenull

由于您从未初始化DownloadStream属性,因此它是nulla.DownloadStream?.FinishedDownloading因此返回值bool?的{​​{1}},因为null 传播空值

?.是正确的,因为它们是两个完全不同的值。

如果您初始化null != false属性,例如通过这样做:

DownloadStream

然后,您将看到class A { public B DownloadStream { get; set; } = new B(); }; 将返回a.DownloadStream?.FinishedDownloading != false,这正是您所期望的。