if 条件可空

问题描述 投票:0回答:10

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;

还有更多。

为什么

if
条件与 Nullable 不起作用?

if (x)
{} 

它出现编译器错误,指出无法将

Nullable<bool>
转换为
bool

为什么它没有被解析为
if (x.HasValue && x.Value == true)
或类似的东西?

这是

Nullable<bool>

最明显的用法
c# .net nullable
10个回答
26
投票

这是

Nullable<bool>

最明显的用法

你的“明显”行为会导致许多不明显的行为。

如果

if(x)

当 x 为 null 时被视为 false,那么会发生什么

if(!x)

? 当 x 为 null 时,

!x
也为 null,因此也将被视为 false!无法通过反转来反转条件的行为,这看起来不奇怪吗?

那又如何

if (x | !x)

当然,这应该始终为真,但如果 x 为 null,则整个表达式为 null,因此为 false。

最好通过将这些不明显的情况全部定为非法来避免它们。 C# 是一种“让用户明确表达他们的意思”的语言。

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


15
投票

简单地说,它无法编译,因为规范说它应该编译 -

if
条件需要 boolean-expression - 并且
Nullable<bool>
类型的表达式不是 boolean-expression:

A boolean-expression 是一个产生 bool 类型结果的表达式;直接或通过在某些上下文中应用运算符 true ,如下所示。

但是,解决方法很容易:

if (x.GetValueOrDefault())
{
}

或者可能更清楚:

if (x ?? false)
{
}

后一种方法很有用,因为这意味着如果

x
为空,您可以轻松更改行为,只需将其更改为
x ?? true
即可。


5
投票

null 意味着 false 并不是那么明显。空值意味着该值未知或未初始化。未知该值是 true 还是 false。谁说 null 应该表现得像 false?

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


3
投票

我认为这不是一个好主意。

null
的计算结果为 false 感觉不自然。特别是在
if+else
陈述中。因此,强制用户明确使用:
if(nb==true)
if(nb==false)
在我看来是个好主意。

MSDN 说:

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

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

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

我的问题的一些答案为什么“bool”上没有提升短路运算符?也涉及这些方面


2
投票

从技术上讲,它不起作用,因为

Nullable<T>
没有定义到
bool
的转换运算符。

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

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

2
投票

这是 Nullable 最明显的用法

要小心这样的言论。对你来说显而易见的事情不一定对其他人来说也是显而易见的。

此外,

if(x) {}

如果 x 是引用类型,也是非法的,因此为了保持一致性,Nullables 的行为应该相同。


1
投票

if 语句中括号之间的任何内容都必须计算为 true 或 false。可空布尔值可以计算为 null、true 或 false。


1
投票

你做不到

if (x)
{...}

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

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

可空布尔值不是布尔值。在某些情况下,您想考虑 null bool?为真,有时你想将其视为假。语言设计不会为你做出这个决定。


1
投票

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

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

无法判断它是否进入了 if 语句,因为 bool 为 null 或 false。这可能是不可取的


1
投票

这是因为可为 null 的 bool 不能隐式转换为 bool。这与您可以这样做的原因相同:

int x1 = 7;
int? x2 = x1;

但你不能这样做:

int? x1 = 7;
int x2 = x1;

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

© www.soinside.com 2019 - 2024. All rights reserved.