代码之家  ›  专栏  ›  技术社区  ›  Asad

Nullable<bool>类型有什么用途?

  •  11
  • Asad  · 技术社区  · 15 年前

    A. 变量可以为true或false,而 也可以为null。

    为什么bool需要第三个值? 如果不是 真的 假的

    你能给我一个我喜欢的场景吗 布尔?

    15 回复  |  直到 15 年前
        1
  •  39
  •   Lee    15 年前

    有些事情可能是真的,也可能是假的,也可能是未定义的,原因有很多。如果一个人只有两个孩子,他会怎么回答“你的第三个孩子是女孩吗?”?正确和错误都是错误的。Null表示比较不适用是恰当的。

        2
  •  16
  •   Aaronaught    15 年前

    各种答案一般讨论了可空类型的重要性。特别是对于可为空的布尔值,还有一个额外的答案。在C#中很难理解,但如果查看任何数据库中的空值逻辑,就很容易理解。

    假设您正在跟踪一个列表或一张表 Shipments Shipment 有一个 DeliveryDate ,但当然,直到发货后很长时间,可能至少在发货实际交付后几天,UPS终于通知您时,您才知道这些信息。所以当然 是一个 Nullable<DateTime> (或 DateTime? ).

    您希望检索上周交付的所有装运的列表。所以你写这个:

    var deliveredThisWeek = shipments.Where(s => 
        s.DeliveryDate >= DateTime.Today.AddDays(-7));
    

    是否应使用 null .)

    var deliveredBeforeThisWeek = shipments.Where(s =>
        s.DeliveryDate < DateTime.Today.AddDays(-7));
    

    是否应使用 无效的 这些 结果?答案是 还是没有

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

    即使是这一次,也无法获得所有结果:

    var deliveredAnytime = shipments.Where(s =>
        (s.DeliveryDate >= DateTime.Today.AddDays(-7)) ||
        (s.DeliveryDate < DateTime.Today.AddDays(-7)));
    

    为了准确地表示此逻辑,您需要一个不正确的条件

    [DeliveryDate >= BeginningOfWeek] = NULL
    [DeliveryDate <  BeginningOfWeek] = NULL
    

    清晰地 NULL OR NULL 还是 NULL TRUE . 这就是为什么你可以正确地说一批货没有在本周开始前交付, 之后没有交货。或者,更准确地说,我们没有 不能 可以放心地说

    但C#并非如此一致。在C#中,如果 为空,则:

    (s.DeliveryDate >= beginningOfWeek) == false
    (s.DeliveryDate < endOfWeek) == false
    

    var deliveredThisWeek = shipments.Where(s =>
        !(s.DeliveryDate < DateTime.Today.AddDays(-7));
    

    啊哈。。。现在它又回来了 无效的 “@Aaronaught,你在说什么,当然是对的!这些货物在上周之前没有交付,因此条件应涵盖这些货物!” ,停下来想一想。

    无效的 但这并不意味着他们没有交货。这个 意味着我们没有 知道 交货日期 就像两周前一样,我们刚刚获取的数据无效。应该有 从该查询返回的实例可能为空,但仍然存在。如果您使用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));
    

    (bool?)null 不等于 false ,因此我们在这两种情况下都得到了正确的结果。

    如果你需要评估一个答案可能是“我不知道”的情况,使用 bool? 可为空<布尔> ) .

    这样,调用方就可以决定如何处理“我不知道”响应,而不是简单地选择默认值。其他任何东西都意味着你的班级 .

        3
  •  10
  •   nickf    15 年前

    null 值表示“无值”或“未知值”。在这种情况下,它既不是真的也不是假的,但是 未定义 .

    http://en.wikipedia.org/wiki/Many-valued_logic

        4
  •  6
  •   George Handlin    15 年前

    当一些问题还没有得到回答时,这很好——想想问卷调查。您有一个y/n问题列表,只有一些问题得到了回答。您不希望将true或false发布到数据库表中,因为用户尚未回答问题。

        5
  •  3
  •   SQLMenace    15 年前

        6
  •  3
  •   ChaosPandion    15 年前

    懒惰编程!

    public bool MyProp
    {
        get { return (myProp = myProp ?? GetPropValue()).Value; }
    }
    private bool? myProp;
    
        7
  •  2
  •   caesay    15 年前

    嗯,我可以看到它被用作“尚未确定”之类的东西,我一直在使用布尔值,有时仅仅两个值是不够的!!例如:

    bool? bl;
    
    bl = true; //Yes
    
    bl = false; //No
    
    bl = null; // Not determined, so do nothing
    

        8
  •  2
  •   John Knoeller    15 年前

    • 我不知道。
    • 目前数据不足
    • 我还没拿定主意
    • 利润

    Mu

        9
  •  2
  •   Michael Stum    15 年前

    我在一个筛选值中使用了它。基本上,我在数据库中有一个bool字段,但我想要三种状态:仅返回值为true的行,仅返回值为false的行,不过滤并返回所有行。

    如果没有可为空的bool,我将不得不使用enum或第二个bool来确定“Filter by this field yes/no”,这将增加bloat。

        10
  •  1
  •   Onorio Catenacci    15 年前

    如果您的程序可能需要知道bool的设置或初始化,那么可以为null表示bool尚未设置或初始化

        11
  •  1
  •   Matt Cullinan    8 年前

    如果您将使用可空布尔值,我将考虑使用枚举或其他数据结构来代替。它可以帮助您避免在不知道NULL的含义时出错。

    然后,我看到了这篇文章和李接受的答案。

    因为我们不知道NULL是什么意思,因为它绝对不是真的(因为,它怎么可能是真的?),所以最好的答案是假的。

    另外,如果这个问题确实返回NULL,那么我们已经为域引入了一个新的定义。这个定义的范围是什么?

    是的,托马斯去了酒吧(最有可能的答案(如果你认识托马斯) 错不,托马斯没有去酒吧。 在第一次计算中,出现了一些可知的错误。你问托马斯这个问题,但他回答时打了个喷嚏,使你一时失聪。只要再问他一次,你就会得到答案。

    不知何故,酒吧被烧毁了,托马斯逃走了。没有现实的方法可以得到答案(请不要在这上面戳洞,但我知道你会的)

    不适用,请参见上面关于三个孩子的示例,但是,请参见bars和Thomas。

    空在这里是什么意思?必须根据具体情况确定空值的含义。这就是为什么我认为使用枚举或其他结构通常更好,因为它更优雅地揭示了非二进制返回值背后的意图。

        12
  •  0
  •   delete delete    15 年前

        13
  •  0
  •   jason    15 年前

    假设订单已经下了,但还没有发货。它的价值是什么 Order.ShippedDate

    处理这个问题的老式方法是使用一个神奇的值,比如 DateTime.MinValue bool

    因此,现代方法是允许 订单装运日期 接受语义上捕获订单尚未发货的值。这就是可空类型所扮演的角色。你应该在语义上思考的一个实例 Nullable<T> HasValue 存在 false

    此外,数据库长期以来允许列允许 null int S同样,您可以使用上面提到的方法,但是如果语言有一个内置的工具,用于从语义上捕获我们试图建模的情况,那么就更好了。

        14
  •  0
  •   Igor Zevaka    15 年前

    Parent1(readonly: true, evaluates true)
      |-Parent2(readonly: null, evaluates true)
        |-Child1(readonly: false, evaluates false)
        |-Child2(readonly: null, evaluates true)
     |-Parent3(readonly: false, evaluates false)
        |-Child1(readonly: false, evaluates false)
        |-Child2(readonly: null, evaluates false)
    
        15
  •  0
  •   Tomas Petricek    15 年前

    NULL 值,当将它们映射到C#时,这是一个问题。可空类型允许您非常优雅地处理此问题-您可以使用 int? , bool? 等等。例如,它们用于LINQ到SQL。