“bool”和“bool?”有什么区别?

63

我在变量中使用“bool”类型,就像我在C++中习惯的那样,我尝试将我期望是布尔值的函数或属性的值放入我的变量中。但是,我经常遇到结果类型为“bool?”而不是“bool”的情况,并且隐式转换失败。

这两者之间有何区别?它们各自在什么时候使用?另外,我应该将“bool?”作为我的变量类型吗?这是最佳实践吗?


可能是在C#中"DateTime?"的含义是什么?的重复问题。 - nawfal
这似乎不是重复的。这是一个浮现在脑海中的问题。就像我一样。谢谢。 - MindRoasterMir
9个回答

100
在类型后面加上"?"符号只是 Nullable type 的一种快捷方式,bool? 等同于 Nullable<bool>bool 是一个 value type,这意味着它不能为 null,因此 Nullable 类型基本上允许您包装值类型,并能够将 null 赋给它们。 bool? 可以包含三个不同的值:truefalsenull
另外,bool? 没有定义短路运算符(&& ||)。
只定义了逻辑 AND、包容性 OR 运算符,它们的行为如下:
x        y      x & y   x | y   
true    true    true    true
true    false   false   true
true    null    null    true
false   true    false   true
false   false   false   false
false   null    false   null
null    true    null    true
null    false   false   null
null    null    null    null

Nullable类型基本上是一个泛型结构体,具有以下公共属性:

public struct Nullable<T> where T: struct
{
    public bool HasValue { get; }
    public T Value { get; }
}
< p > HasValue 属性指示当前对象是否具有值,而 Value 属性将获取对象的当前值,或者如果 HasValue 为 false,则会引发 InvalidOperationException 异常。

现在你一定在想什么,Nullable 是一个结构体,这是一个不能为 null 的值类型,那么为什么下面的语句是有效的呢?

int? a = null;

这个例子将编译成这样:

.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0)
IL_0000:  ldloca.s   V_0
IL_0002:  initobj    valuetype [mscorlib]System.Nullable`1<int32>

调用initobj,它会将指定地址上的值类型的每个字段初始化为null引用或相应基元类型的0。

这就是默认的struct initialization发生的情况。

int? a = null;

等同于:

Nullable<int> a = new Nullable<int>();

3
这是一个很好的答案,但我可以建议您明确指出bool?也是一种值类型,它实际上是一个包含类似{T value; bool _hasValue}的结构体。 - AnthonyWJones
谢谢Anthony,我稍微扩展了一下我的帖子。 - Christian C. Salvadó
!((bool?)null) 的结果是 null - Second Person Shooter

18

bool?是可空类型,而bool不是。

bool? first;
bool second;
在上面的代码中,first将会是null,而second将会是false
一个典型的用途是想要知道变量是否已经被分配了值。由于bool是一个“值类型”(与intlongdoubleDateTime和一些其他类型一样),它将始终初始化为默认值(在bool的情况下为false,在int的情况下为0)。这意味着你无法轻易地知道它是因为某些代码分配了false给它,还是因为它尚未被分配而是false。在这种情况下,bool?就派上用场了。

9
请注意,这些默认值仅适用于实例/静态变量,而不适用于局部变量。 - Jon Skeet

6
每当您看到类型名称后面跟着 ? 字符时,它是 Nullable<TypeName> 的缩写。Nullable 是一种特殊的类型,允许值类型像空值一样运作。这是明确表示值类型可以有非值值的一种方式。
对于布尔值,它有效地将变量转换为三态值:
- 有值:True - 有值:False - 没有值

5

添加 ? 使类型可为空。这意味着你可以这样做:

bool? x = null;

这完全没问题。


4

在需要进行空值检查的方法中,使用bool?也是一个不错的选择。

public bool? IsTurkeyStillInFridge(Turkey turkey)
{
  if (turkey == null)
     return null;
  else if (fridge.Contains(turkey))
     return true;
  else
     return false;
}

bool? canStayAtDesk = IsTurkeyStillInFridge(turkey);

if (canStayAtDesk == null)
    MessageBox.Show("No turkey this year, check for ham.");
else if (canStayAtDesk == true)
    MessageBox.Show("Turkey for lunch. Stay at desk.");
else
    MessageBox.Show("Turkey's gone, go out to lunch.");

3

bool? 表示布尔值可以为 null,是结构体 Nullable<bool> 的语法糖。因为布尔值是值类型,所以不能将其设置为 null,但在某些情况下,比如在数据访问类中,你可能需要这样做,因为数据库字段可以有空值。


2

bool 只能包含 truefalse 两个值,而 bool? 还可以有一个 null 值。


1
声明时带有 (double?) 表示该变量可为空。
double i1=0.2; //ok
double i2=null; //not ok

double? i3=0.1; //ok
double? i4=null; //ok

0

bool 表示你可以有 true 和 false 的值。 bool? 表示你可以有 true、false 和 null 的值。

它适用于日期时间和布尔值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接