布尔型返回类型 bool? 是什么意思?

11

我看到一个方法返回 bool?,有人知道它的含义吗?

3个回答

25
T? 是 C# 语法中 Nullable<T> 的简写。因此,bool? 映射到 Nullable<bool>。所以在您的情况下,它是一个结构体,可以是 null,也可以是一个 bool 值。
如果 Nullable<T>null,那么与引用类型为 null 不同。它基本上是一个包含基础类型和布尔标志 HasValue 的结构体。但是,运行时和 C# 语言都有一些魔法来假装具有 HasValue==falseNullable 实际上是 null。但是差异有时仍会泄漏出来。
基础类型可以隐式转换为可空类型(bool->bool?)。要从可空类型获取基础类型,可以显式转换((bool)myNullableBool)或使用 Value 属性(myNullableBool.Value)。但是,在此之前应检查是否为 null,否则如果可空值为 null,将会抛出异常。

13
在C#中,“基元(primitive)”类型无法保存空值:
int blah = null;

这会导致异常,因为'int'不能包含空值。

同样适用于double、float、bool和DateTime等类型...

这没有问题。问题在于当你使用数据库时。在数据库中,行可以是空的,比如年龄(这是一个int)。

你如何在对象上保存该行?你的int无法保存空值,但行可以为空。

因此,微软创建了一个新的结构体,Nullable,你可以将一个“原始”类型(或一个结构体)传递给该结构体,使它成为可空的,例如:

Nullable<int> blah = null;

现在这样做不会产生异常,因为该变量可以保存int和null。

由于Nullable太长了,微软创建了一种别名:如果在类型后面添加“?”,它就变成可空类型:

int? blah = null;
Nullable<int> blah = null;
这两行代码完全一样,但第一行更易读。像这样:)

这是一个结构体,而不是类。它接受其他结构体作为参数,而不仅仅是原始类型。 - xanatos
这只是为了稍微解释一下,没有详细说明,但你说得对,我会改的 :) - Jesus Rodriguez

5

任何(不废话的1)带有?后缀的值类型都会变成可空类型:

  • int?是可空整型
  • bool?是可空布尔类型,实际上是一个三态布尔类型truefalsenull),在需要实现一些三态行为时请考虑使用。
  • ...

换句话说,object类型不支持可空定义,因为它是引用类型,已经可以具有null值。

实际应用

可空类型最常用于数据库中,因为它们使得将可空的int/bit/datetime等列转换为CLR类型非常容易。例如:

create table Test
(
    Id int identity not null primary key,
    Days int null,
    ExactDate datetime null,
    Selected bit null
)

这可以轻松地转换为POCO:
public class Test
{
    public int Id { get; set; }
    public int? Days { get; set; }
    public DateTime? ExactDate { get; set; }
    public bool? Selected { get; set; }
}

1 no-nonsense 指的是除了Nullable<T>之外的所有值类型,因为Nullable<T>本身就是一个值类型,将其置为空并没有任何意义... 避免这种愚蠢的行为... 它无论如何都不会编译通过,因为Nullable<Nullable<int>> i = null;可以被解释为两种方式:

i.HasValue == false
i.HasValue == true && i.Value.HasValue == false


@Robert 任何具有默认构造函数的值类型。Nullable<Nullable<int>> 不是有效的。 :-) - xanatos
你可能想要写 T?,然后提供一个可空的 T。有时会出现这样的情况,这将非常有用。 - CodesInChaos
@xanatos:我会期望编译器明确检查这种情况。你如何解释 x = null 这个赋值语句?它应该是 x.HasValue == true 以及 x.Value.HasValue == false 还是 x.HasValue = false 呢? - Robert Koritnik
@Robert,“真正的”HasValue只会保存在“外部”Nullable中。当HasValue = true时,“外部”和“内部”Value都将被设置(并且内部HasValue将被设置为true)。 “外部”可空将完全掩盖“内部”可空。它仅作为通用参数有用。您收到T并希望在不检查T是否已可空的情况下在内部使用T? - xanatos
@Robert 但是我发现你不能将int?传递给一个泛型类“where T:struct”……这是一个有趣的世界,可空类型的世界。充满了奇妙的魔力。 :-) - xanatos
显示剩余4条评论

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