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?
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>
tobool
. There is an implicit conversion frombool
toNullable<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 justbool
, notNullable<bool>
).In other words, the expression
fred == false
is of typebool
, whereas the expressionfred
is of typeNullable<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?
.