Nullable <bool>类型有什么用?

Asa*_*sad 12 c# boolean nullable

一个布尔变量可以保持真或假,而布尔?也可以为空.

为什么我们需要bool的第三个值?如果它不是真的,它是什么,它是== false

你能建议一个我喜欢布尔的场景吗?代替.

谢谢

Lee*_*Lee 34

出于多种原因,某些事情可能是真实的,错误的或未定义的.如何回答"你的第三个孩子是女孩吗?" 如果一个人只有两个孩子?真假都是不正确的.Null适合说比较不适用.

  • 或者枚举可能是更好的选择. (5认同)
  • 对这个问题只有一个恰当的回答:MU. (4认同)
  • 假是对你的假设问题的完全有效的答案。如果您对“您有第三个孩子吗”这一具体问题感兴趣,请提出该问题。如果您需要更复杂的语义,例如“未设置此参数”或“该人拒绝回答”,请遵循@kenny 的建议并使用枚举。避免使用“bool?”,除非有充分的理由。 (2认同)

Aar*_*ght 14

各种答案一般讨论可空类型的重要性.可以为null的布尔值提供额外的答案.在C#中很难理解,但如果你在任何数据库中查看空值逻辑,那么很容易理解.

假设您正在跟踪列表或表格Shipments.A Shipment有一个DeliveryDate,但当然你不知道这些信息,直到货物发货很久,并且可能至少在货物实际发货后几天,当UPS终于到处通知你.所以当然DeliveryDateNullable<DateTime>(或DateTime?).

您想要检索上周交付的所有货件的清单.所以你写这个:

var deliveredThisWeek = shipments.Where(s => 
    s.DeliveryDate >= DateTime.Today.AddDays(-7));
Run Code Online (Sandbox Code Playgroud)

是否应null包含交货日期的货件?(答案当然是否定的.)

好的,那么这个怎么样:

var deliveredBeforeThisWeek = shipments.Where(s =>
    s.DeliveryDate < DateTime.Today.AddDays(-7));
Run Code Online (Sandbox Code Playgroud)

是否应将null包含交货日期的货件包含在这些结果中?答案仍然否定的.

所以现在你有一个奇怪的情况.您可能会认为在这两个查询之间,您将收到系统中的所有货件. A | !A总是true,对吗?不是在你处理空值时.

即便是这个也无法得到你所有的结果:

var deliveredAnytime = shipments.Where(s =>
    (s.DeliveryDate >= DateTime.Today.AddDays(-7)) ||
    (s.DeliveryDate < DateTime.Today.AddDays(-7)));
Run Code Online (Sandbox Code Playgroud)

那怎么可能呢?

为了准确地表示此逻辑,您需要一个不是真假的条件.而且,C#在这里是一个不好的例子,因为它没有像你真正期望的那样实现逻辑.但在SQLese中,它是有道理的,因为:

[DeliveryDate >= BeginningOfWeek] = NULL
[DeliveryDate <  BeginningOfWeek] = NULL
Run Code Online (Sandbox Code Playgroud)

显然,NULL OR NULL仍然是NULL,不是TRUE.这就是为什么你可以正确地说货物在本周开始之前没有交付,并且之后没有交付.或者,更准确地说,我们不知道它何时交付,因此我们无法安全地说它确实符合这些条件.

但C#并不是那么一致.在C#中,如果DeliveryDate为null,则:

(s.DeliveryDate >= beginningOfWeek) == false
(s.DeliveryDate < endOfWeek) == false
Run Code Online (Sandbox Code Playgroud)

这为我们上面的查询提供了正确的答案,所以你可能会试图说常规布尔逻辑足够好,除了这个混乱之外:

var deliveredThisWeek = shipments.Where(s =>
    !(s.DeliveryDate < DateTime.Today.AddDays(-7));
Run Code Online (Sandbox Code Playgroud)

啊啊......现在它给我们回复null交货日期!这不对!在有人说"@Aaronaught,你在谈论什么,当然是对的!那些货物在上周之前没有交付,所以情况应该覆盖他们!" ,停下来思考一下.

NULL实际上并不意味着他们没有交付.在NULL我们没有办法知道,当他们被交付.职员可能会在明天拿到确认函,并在DeliveryDate两周前填写,以使我们刚拿到的数据无效.应该有来自该查询的空实例,但是有.如果在SQL中编写相同的查询,则会排除这些结果.

所以,你为什么要关心Nullable<bool>C#何时没有?因此,您可以避免在自己的代码中陷入此陷阱:

public static bool? IsThisWeek(DateTime? dt)
{
    return (dt != null) ? (bool?)(dt.Value > DateTime.Today.AddDays(-7)) : null;
}

var deliveredBeforeThisWeek = shipments.Where(s =>
    (!IsThisWeek(s.DeliveryDate) == true));

// Or, the equivalent:
var alsoDeliveredBeforeThisWeek = shipments.Where(s =>
    (IsThisWeek(s.DeliveryDate) == false));
Run Code Online (Sandbox Code Playgroud)

这有点尴尬,但是正确的.我们编写了一个或多或少正确地传达其意图的查询,(bool?)null并不等于true false,因此我们在两种情况下都得到了正确的结果.

如果您需要评估答案可能是"我不知道"的情况 - 请使用bool?(AKA Nullable<bool>)作为结果.

这样,调用者可以决定如何处理"我不知道"的响应,而不是简单地选择默认值.别的什么意味着你的班级撒谎.


nic*_*ckf 10

一个null值表示"无值"或"未知值".在这种情况下,它不是真的,也不是假的,而是未定义的.

请参阅:http://en.wikipedia.org/wiki/Many-valued_logic

  • 有些人称之为"bool?"三态.:-) (4认同)

小智 5

当某些事情尚未得到回答时,这是好事 - 想想问卷调查.你有一个y/n问题列表,只有一些已被回答.您不希望将true或false发布到数据库表,因为用户尚未回答该问题.