Asa*_*sad 12 c# boolean nullable
一个布尔变量可以保持真或假,而布尔?也可以为空.
为什么我们需要bool的第三个值?如果它不是真的,它是什么,它是== false
你能建议一个我喜欢布尔的场景吗?代替.
谢谢
Lee*_*Lee 34
出于多种原因,某些事情可能是真实的,错误的或未定义的.如何回答"你的第三个孩子是女孩吗?" 如果一个人只有两个孩子?真假都是不正确的.Null适合说比较不适用.
Aar*_*ght 14
各种答案一般讨论可空类型的重要性.可以为null的布尔值提供额外的答案.在C#中很难理解,但如果你在任何数据库中查看空值逻辑,那么很容易理解.
假设您正在跟踪列表或表格Shipments
.A Shipment
有一个DeliveryDate
,但当然你不知道这些信息,直到货物发货很久,并且可能至少在货物实际发货后几天,当UPS终于到处通知你.所以当然DeliveryDate
是Nullable<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