Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AND operation cannot be applied between nullable bools

I am applying AND operation (&&) between two nullable boolean (bool?) but it is giving me error that

Operator && cannot be applied to operands of type bool? and bool?

How do i apply and operation in my statement that contains two nullable bools?

Also if i have a dialog result like

dialog.ShowDialog () == DialogResult.OK

How can I convert it to nullable bool as i need to put '&&' operator with this in an if condition whose other operand returns a nullable bool? Here is code:

if (dialog.ShowDialog () == DialogResult.OK && CheckProjectPath(dialog.FileName, true))

the second operand in this if condition is a nullable bool.

like image 724
ghd Avatar asked Dec 03 '10 19:12

ghd


1 Answers

How do i apply and operation in my statement that contains two nullable bools?

Well, what do you want to happen? The reason this is illegal is because bad things happen if the first operand is null.

What does x && y mean for nullable Booleans x and y? Well, what does a nullable Boolean mean in the first place? A nullable Boolean means one of three things:

  • The condition is definitely true
  • The condition is definitely false
  • The condition is true or false but we do not know which one

So what does x && y mean? It means "evaluate y only if condition x is true", but if x is nullable then we might not know whether the condition represented by x is true or not.

For example, suppose we have:

gotMoneyInZurich = SalesForNovemberWereMoreThanAMillionBucks() &&
    TryToDepositAMillionBucksInASwissBankAccount();

If SalesForNovemberWereMoreThanAMillionBucks is false, then don't try to deposit the money, and we know we have no money in the bank. If it is true, then try to deposit the money; if that fails, then we don't have money in Zurich; if it succeeds, we do.

Now suppose that not all the salespeople have reported their sales figures for November yet. Do we know whether sales for November were more than a million bucks? No. November is in the past; either the sales were, or they weren't more than a million bucks, but right now we don't know. The correct answer is not "false", the correct answer is not "true": the correct answer is "we don't know": null.

So what should this do if null is returned by the first operand? We don't know whether sales were more than a million bucks, so is the right thing to do to try to deposit the money, or to not try to deposit the money? Should you take action on the basis of missing information, or not?

The compiler has no ability to decide this question for you. If you want to not deposit the money if the result is unknown, then you have to say that:(SalesForNovemberWereMoreThanAMillionBucks() ?? false) means "if the result was null, treat it as though it were false".

Similarly, if you say:

if(x && y)
    Frob();

and x is true, and y is null, then what should you do? You are saying "Frob only if x and y are both true. x is true, and we don't know whether y is true or not". So should you Frob or not? You don't know. The compiler doesn't know either. If what you want to say is "Frob if x is true and y is either true or null" then say that:

if(x && (y ?? true))
    Frob();

Or, "frob if x is true and y is true, but not if y is null" then say that:

if(x && (y ?? false))
    Frob();

Now, if you are not using the && operator for the purposes of short-circuiting evaluation then don't use the && operator in the first place. Use the & operator; it always evaluates both sides, so there is no ambiguity here. It is perfectly legal to say x & y if x and y are nullable bools. You still can't use that thing in an if of course; that requires a bool, not a nullable bool. But you can say: bool? result = x & y; where x and y are nullable bools.

like image 198
Eric Lippert Avatar answered Sep 25 '22 10:09

Eric Lippert