C# 布尔?与布尔与GetValuerDefault与??操作人员

C# 布尔?与布尔与GetValuerDefault与??操作人员,c#,nullable,C#,Nullable,对于数字,它总是一样漂亮: 有以下几种选择: if(b == false) { ... } // looks ugly, comparing bool? with bool if(b.GetValueOrDefault()) { ... } // unclear when condition is true (one must know it's `false`) if(b.GetValueOrDefault(true)) { ... } // required few seconds to u

对于数字,它总是一样漂亮:

有以下几种选择:

if(b == false) { ... } // looks ugly, comparing bool? with bool
if(b.GetValueOrDefault()) { ... } // unclear when condition is true (one must know it's `false`)
if(b.GetValueOrDefault(true)) { ... } // required few seconds to understand inversion
每当nullables(至少
bool?
)应该使用这种语法时,我总是很好奇

if(b ?? false) { ... } // looks best to me

旁白:这看起来像是一个基于意见的问题,但我并没有发现类似的问题可以单独消除我所有的疑虑。。。也许其中一些最适合在某些场景中使用,我想知道在哪些场景中使用。

语言设计者有两种选择,允许
bool?
参与需要
bool
的控制语句的控制表达式:

  • 允许它,并在涉及
    null
    治疗时做出任意决定
  • 不允许,强迫你在每次相关的时候做出决定
请注意,设计者对if(a<123)语句的问题很少,因为“no”是对问题的有效回答,“is
null
小于123”、“is
null
大于123”、“is
null
等于123”等等


if(b??false)
if(b??true)
是非常方便的构造,可以让您向代码的读者和编译器解释您希望以何种方式处理存储在
bool?
变量中的
null

每次我看到有人使用可为null的布尔值
bool?
,我问他们为什么。通常,答案是“嗯,我不是很确定”。它实际上创造了一个三态条件,在我看来,这使得代码更难阅读。null意味着什么,如果它总是假的,那么为什么要首先让它可以为null呢

但是为了更直接地回答你的问题,我更喜欢

if (b ?? false)
网络上的语法

if (b.GetValueOrDefault())

几年后,根据我个人的经验,我可以看出以下语法显然是一个赢家:

if(b == false) { /* do something if false */ }
if(b == true) { /* do something if true */ }
if(b != false) { /* do something if NOT false, means true or null */ }
if(b != true) { /* do something if NOT true, means false or null */ }
我认为“丑陋”的东西最容易理解

==vs?? 空值通常是linq查询的结果,使用
会增加不必要的复杂性以了解情况

比较

if(Items?.Any(o => o.IsSelected) == true)
vs

第一个更容易阅读,它是一个简单的检查,如果任何项目被选中


当我(可能是未经训练的?)的大脑读到后者时,我必须在
上做一个心理上的句号,做倒装,只有这样我才能理解
块何时执行。有了
,如果时间足够长,我很可能会在快速浏览别人编写的代码甚至自己编写的代码时出错。

如果
bool
为空,您希望发生什么?是否应执行
if
块,是否应执行
else
块,或者两者都不执行?答案取决于此,你的例子在这方面做了不同的事情。@Heinzi,我故意选择了最令人困惑的案例。想象一下你读了别人的代码,或者你必须为别人写一个。您将使用哪个选项?为什么?这是否意味着您更喜欢自己的解决方案?在我看来,它是最干净的,指出了
b
可以
null
的内容,并以最容易理解的方式将
null
包含在条件中。@Sinatr绝对地,
??
是处理null中
null
值的最干净的解决方案。有趣的是,C设计者选择了选项2,然而VB.NET设计者(不幸地)选择了选项1。Nullables非常有用(回答您的问题“为什么”)。随着C#6.0
?。
(空条件运算符)的出现,您将看到更多。请不要误会,我一直在使用它们——但我尝试在可能的情况下避免使用它们,特别是对于布尔值,因为这对我来说是二进制的。三态bool并不是真正的最佳实践,特别是如果null总是错误的话。大多数时候,对我来说,bool?如果(MyList?.FirstOrDefault(a=>a==b)?.Value==c)避免列表的if,结果的if清楚地表明列表和搜索的元素可以为空,甚至可以扩展到值。
if(b == false) { /* do something if false */ }
if(b == true) { /* do something if true */ }
if(b != false) { /* do something if NOT false, means true or null */ }
if(b != true) { /* do something if NOT true, means false or null */ }
if(Items?.Any(o => o.IsSelected) == true)
if(Items?.Any(o => o.IsSelected) ?? false)