Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bool? compare with bool vs GetValueOrDefault vs ?? operator

Tags:

c#

nullable

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.

like image 642
Sinatr Avatar asked Nov 16 '15 13:11

Sinatr


People also ask

Can a boolean be null C#?

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.

What is GetValueOrDefault return?

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.

What is the default value of Boolean in C#?

The default value of the bool type is false .


3 Answers

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.

like image 113
Sergey Kalinichenko Avatar answered Sep 24 '22 10:09

Sergey Kalinichenko


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())
like image 34
David Pine Avatar answered Sep 23 '22 10:09

David Pine


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.

like image 24
Sinatr Avatar answered Sep 25 '22 10:09

Sinatr