With numeric it is always same pretty:
if(a < 123) { ... } // disregards if `b` is `int?` or `int`
But with bool?
:
bool? b = ...
if(b) { ... } // compiler error: can't convert bool? to bool.
There are following options:
if(b == false) { ... } // looks ugly, comparing bool? with bool
if(b.GetValueOrDefault()) { ... } // unclear when condition is true (one must know it's `false`)
if(b.GetValueOrDefault(true)) { ... } // required few seconds to understand inversion
I was curios whenever nullables (at least bool?
) deserves this syntax to be used always:
if(b ?? false) { ... } // looks best to me
P.S.: this may looks like opinion-based question, but I didn't find similar to clear all my doubts alone... Perhaps some of those are best used in certain scenarios and I'd like to know in which ones.
C# has two different categories of types: value types and reference types. Amongst other, more important distinctions, value types, such as bool or int, cannot contain null values. You can, however, use nullable version of value types.
The GetValueOrDefault method returns a value even if the HasValue property is false (unlike the Value property, which throws an exception). If the HasValue property is false , the method returns the default value of the underlying type.
The default value of the bool type is false .
The language designers had two choices, as far as allowing bool?
to participate in control expressions of control statements requiring a bool
:
null
treatmentNote 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 null
s 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With