如果条件可以为空

时间:2012-01-18 14:22:43

标签: c# .net compiler-construction nullable

Nullable<T>有很多语法糖,如:

int? parsed to Nullable<int>

int? x = null
   if (x != null) // Parsed to if (x.HasValue)

x = 56; // Parsed to x.Value = 56;

还有更多。

为什么使用Nullable的if条件不起作用?

if (x)
{} 

导致Complier错误,无法将Nullable<bool>转换为bool 为什么它没有被解析为if (x.HasValue && x.Value == true)或类似的东西?

这是Nullable<bool>

最明显的用法

10 个答案:

答案 0 :(得分:22)

  

这是Nullable<bool>

最明显的用法

你的&#34;显而易见的&#34;行为导致许多不明显的行为。

如果

if(x)
当x为null时,

被视为false,那么

会发生什么
if(!x)

?当x为null时,!x也为null,因此也将被视为false!你不能用反转反转条件的行为似乎并不奇怪吗?

怎么样?
if (x | !x)

当然应该总是如此,但如果x为null,则整个表达式为null,因此为false。

最好通过简单地将它们全部视为非法来避免这些不明显的情况。 C#是一个&#34;让用户毫不含糊地说出他们的意思&#34;语言。

我相信VB有你想要的行为。如果您喜欢这种情况,可以考虑切换到VB。

答案 1 :(得分:11)

简单地说,它无法编译,因为规范说它应该 - if条件需要布尔表达式 - 并且类型Nullable<bool>的表达式不是a 布尔表达式

  

boolean-expression 是一个表达式,它产生bool类型的结果;直接或通过在以下指定的某些上下文中应用operator true。

然而,它很容易解决:

if (x.GetValueOrDefault())
{
}

或者可能更清楚:

if (x ?? false)
{
}

后一种方法很有用,因为这意味着如果x为空,只需将其更改为x ?? true即可轻松更改行为。

答案 2 :(得分:5)

并不是那么明显,null应该是假的。空值表示该值未知或未初始化。不知道该值是真还是假。谁说null应该表现得像假?

Nullable<bool>的一个更明显的用法是存储可以是真或假的东西,但有时是不相关或未知的,在这种情况下,值为null。

答案 3 :(得分:3)

我认为这不是一个好主意。那个null评估为false并不自然。特别是在if+else陈述中。因此,强制用户明确:if(nb==true)if(nb==false)是一个好主意IMO。

MSDN说:

bool? b = null;
if (b) // Error CS0266.
{
}
     

这是不允许的,因为不清楚null在条件的上下文中意味着什么。使用bool?在条件语句中,首先检查其HasValue属性以确保其值不为null,然后将其强制转换为bool。有关更多信息,请参阅bool。如果你对布尔执行演员表演?值为null时,将在条件测试中抛出InvalidOperationException。

http://msdn.microsoft.com/en-us/library/bb384091.aspx

我的问题Why are there no lifted short-circuiting operators on `bool?`?的一些答案也涉及这些方面

答案 4 :(得分:2)

从技术上讲,它不起作用,因为Nullable<T>未将转化运算符定义为bool

实际上,由于各种原因,它不受支持,包括:

  • 在C#中的任何地方都没有隐式转换为bool - 为什么应该在Nullable<T>
  • 必须为T中的每个Nullable<T>声明任何可用的转换 - 当您可以将自己的类型插入编译器一无所知的T时,这怎么可能? ?
  • if(!x)的语义是什么?

答案 5 :(得分:2)

  

这是Nullable

最明显的用法

小心那样的陈述。对你来说,显而易见的并不一定是对其他人来说显而易见的事情。

此外,

if(x) {}
如果x是引用类型,

也是非法的,因此为了保持一致性,Nullables的行为应该是相同的。

答案 6 :(得分:1)

if语句的括号之间的任何内容都必须求值为true或false。可以为空的bool可以评估为null,true或false。

答案 7 :(得分:1)

你做不到

if (x)
{...}

出于完全相同的原因你不能写

int? a = null;
var b = a + 1;

可以为空的布尔值不是布尔值。在某些情况下,你想考虑一个空bool?同样如此,有时候你想把它当作假的。语言设计不会为您做出决定。

答案 8 :(得分:1)

考虑在这种情况下会发生什么

bool? nullBool = null;
if (nullBool)
{
    someCode();
}

由于bool为null或false,因此无法判断它是否输入了句子。这可能是不可取的

答案 9 :(得分:1)

这是因为无法将可空的bool隐式转换为bool。这就是为什么你能做到这一点的原因:

int x1 = 7;
int? x2 = x1;

但你不能这样做:

int? x1 = 7;
int x2 = x1;

如果它包含值,您必须先检查。使用可空类型进行隐式转换只能在分配值时进行,而不能在使用该值时进行。