开发者

What is the use of Nullable<bool> type?

a bool variable could hold true or false, while bool? could be null as well.

Why would we need a third value for bool ? If it is not true, what ever it is, it is == fals开发者_运维知识库e

Can you suggest a scenario where I would fancy a bool? instead.

Thanks


Something can be true, false or undefined for many reasons. How would one answer "Is your third child a girl?" if one only has two children? Both true and false are incorrect. Null would be appropriate as saying that the comparison doesn't apply.


Various answers discuss the importance of nullable types in general. There is an additional answer for the nullable boolean, specifically. It's hard to understand in C#, but very easy to understand if you look at null-valued logic in any database.

Let's say you're tracking a list or table of Shipments. A Shipment has a DeliveryDate, but of course you don't know this information until long after the shipment has been made, and probably at least a few days after the shipment was actually delivered, when UPS finally gets around to notifying you. So of course the DeliveryDate is a Nullable<DateTime> (or DateTime?).

You want to retrieve a list of all shipments that were delivered during the last week. So you write this:

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

Should shipments with a null delivery date be included? (The answer is, of course, no.)

OK, so what about this:

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

Should shipments with a null delivery date be included in these results? The answer is still no.

So now you have a curious situation. You might think that between the two of these queries, you would receive all shipments in the system. A | !A is always true, right? Not when you're dealing with nulls.

Even this one fails to get you all the results:

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

So how is this possible?

In order to accurately represent this logic, you need a condition that is not true or false. And again, C# is kind of a bad example here because it doesn't implement the logic the way you'd really expect it to. But in SQLese, it makes sense, because:

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

Clearly, NULL OR NULL is still NULL, not TRUE. That is how you can correctly say that a shipment was not delivered before the beginning of the week, and was not delivered after. Or, more accurately, we don't know when it was delivered, so we can't safely say that it does match either of those conditions.

But C# is not so consistent. In C#, if the DeliveryDate is null, then:

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

Which gets you the right answer for our query above, so you might be tempted to say that regular boolean logic is good enough, except that this one messes it all up:

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

Aha... now it's giving us back null delivery dates! This isn't right! And before someone says "@Aaronaught, what are you on about, of course it's right! Those shipments were NOT delivered before last week, so the condition should cover them!", stop and think about it for a second.

The NULL doesn't actually mean that they weren't delivered. The NULL means that we don't know when they were delivered. It's possible that a clerk will pick up the confirmation tomorrow, and fill in the DeliveryDate as two weeks ago, invalidating the data we just picked up. There should not be null instances coming back from that query, and yet there are. If you wrote the same query in SQL, those results would be excluded.

So, why should you care about Nullable<bool> when C# apparently doesn't? So you can avoid falling into this trap in your own code:

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));

This is a bit awkward, but correct. We've written a query that more or less communicates its intent properly, and (bool?)null does not equate to true or false, so we get the right results in both cases.

If you ever need to evaluate a condition where the answer might be "I don't know" - use a bool? (AKA Nullable<bool>) as the result.

That way, the caller can decide how to handle an "I don't know" response instead of you simply choosing a default. Anything else means your class is lying.


a null value means "no value" or "unknown value". In this case, it's not true nor false, but undefined.

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


It's good for when something hasn't been answered yet - think of a questionnaire. You have a list of y/n questions and only some have been answered. You wouldn't want to post true or false to the database table because the user hasn't answered the question yet.


it could be unknown in addition to true or false..in database land a NULL usually means unknown or no value


Lazy programming!

public bool MyProp
{
    get { return (myProp = myProp ?? GetPropValue()).Value; }
}
private bool? myProp;


Well I could see it being used as a "Not determined yet" kind of thing, i use bools all the time and sometimes just two values isnt enough!! for instance:

bool? bl;

bl = true; //Yes

bl = false; //No

bl = null; // Not determined, so do nothing

in my opinion its just the third value to a bool.


a null value means

  • I don't know.
  • Insufficient data at this time
  • The state of the cat before the box is opened
  • I haven't made up my mind yet
  • Profit

a null value means Mu


I used it in a Filter Value. Basically I have a bool field in the database, but I wanted three states: Only return rows where the value is true, only return rows where the value is false, do not filter and return all rows.

Without a nullable bool I would have to use either an enum or a second bool to determine "Filter by this field yes/no" which would add bloat.


being nullable could indicate that the bool has not be set or initialized if that is something your program might need to know


If you’re about to use a Nullable bool, I would consider using an Enum or other data structure instead. It may help you avoid mistakes when the meaning of NULL is not known.

Recently, I mishandled a Nullable bool. I won’t go into the details of the mistake, but lets just say it was bad enough to require a full rollback. I began to wonder how practical it is to use in most applications. (In part in an attempt to hold on to my broken pride as a result of the stupid mistake

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜