Search code examples
c#null-coalescing-operator

How to null coalesce for Boolean condition?


I'm trying to safely check if an IList<> is not empty.

var Foo = Bar.GimmeIListT(); // Returns an IList<SomeObject>
if (Foo?.Any())
    // Do cool stuff with items in Foo

But there is an error with the condition:

Cannot implicitly convert 'bool?' to 'bool'. An explicit conversion exists (are you missing a cast?)

So it seems the condition evaluates to a nullable bool, so I try

if (Foo?.Any().Value())

But this is no good either:

'bool' does not contain a definition for 'Value' and no extension .... blah blah blah

So in the first instance it complains that it is a nullable bool but in the second it complains that it isn't.

As another avenue I try:

if (Foo?.Any() == true)

This works - but it shouldn't because this uses an implicit conversion which the first message said it didn't want!

What is going on? What is the correct way to do this?


Solution

  • You can compare with the bool? if you use ==, that's indeed the best/simplest approach:

    if (Foo?.Any() == true) ...
    

    as to the why it's not allowed in an if but with ==, Jon Skeet can explain it much better:

    There's no implicit conversion from Nullable<bool> to bool. There is an implicit conversion from bool to Nullable<bool> and that's what happens (in language terms) to each of the bool constants in the first version. The bool operator==(Nullable<bool>, Nullable<bool>) operator is then applied. (This isn't quite the same as other lifted operators - the result is just bool, not Nullable<bool>).

    In other words, the expression fred == false is of type bool, whereas the expression fred is of type Nullable<bool> hence you can't use it as the "if" expression.

    So the if allows only bool and you have a bool?, but the == operator converts the bool to a bool? and you can compare two bool?.