bool? compare with bool vs GetValueOrDefault vs ?? operator

The language designers had two choices, as far as allowing bool? to participate in control expressions of control statements requiring a bool:

  • Allow it, and make an arbitrary decision when it comes to null treatment
  • Disallow it, forcing you to make a decision each time it is relevant.

Note that the designers had much less of an issue with if(a < 123) statement, because "no" is a valid answer to questions "is null less than 123", "is null greater than 123", "is null equal to 123", and so on.

The if (b ?? false) and if (b ?? true) are very convenient constructs, which let you explain to the readers of your code and to the compiler in which way you wish to treat nulls stored in a bool? variable.


Every time I see someone using a nullable boolean bool?, I ask them why. Usually, the answer is -- "well, I'm not really sure". It is effectively creating a three state condition which in my opinion makes the code harder to read regardless. What does null mean, if it is always false then why bother with making it nullable in the first place?

But to answer your question more directly, I prefer the

if (b ?? false)

syntax over the

if (b.GetValueOrDefault())

Some years later and from personal experience I can tell that following syntax is clearly a winner:

if(b == false) { /* do something if false */ }
if(b == true) { /* do something if true */ }
if(b != false) { /* do something if NOT false, means true or null */ }
if(b != true) { /* do something if NOT true, means false or null */ }

What I thought as "ugly" turns out to be the easiest to understand.

== vs ??

Nullables are often results of linq queries and using ?? add unnecessary layer of complexity to understand the condition.

Compare

if(Items?.Any(o => o.IsSelected) == true)

vs

if(Items?.Any(o => o.IsSelected) ?? false)

The first one is much easier to read, it's a simple check if any item is selected.

When my (probably untrained?) mind reads the latter, I have to make a mental full stop at ??, do inversion and only then I understand when if block will be executed. With ?? I am likely to make a mistake when quickly looking throught the code written by someone else or even my own code given enough time has passed.

Tags:

C#

Nullable