Home > Back-end >  C#: Null coalescing operator using nullable bool giving (what I consider) incorrect result
C#: Null coalescing operator using nullable bool giving (what I consider) incorrect result

Time:08-11

I ran into a weird scenario today and I am just wondering if anyone can explain why I am seeing what I am seeing below.

I would expect all of the following statements to evaluate to True, but when a nullable bool is set to False it evaluates to False.

I have read the other posts stating that you should give precedence to your operators that use null collation. That works of course but that does not explain why the second expression evaluates to False, which is the question I would like answered.

I even created a Sharplab.io of this. From what I see there is that the True parts of the first two expressions are just being removed. This does not make any sense to me and seems like a bug. You can of course get around it using parentheses, but this behavior seems really weird to me.

bool? nullableBoolEqualNull = null;
bool? nullableBoolEqualFalse = false;

Console.WriteLine(nullableBoolEqualNull ?? false || true); // Evaluates to `True`
Console.WriteLine(nullableBoolEqualFalse ?? false || true); // Evaluates to `False`
Console.WriteLine((nullableBoolEqualNull ?? false) || true); // Evaluates to `True`
Console.WriteLine((nullableBoolEqualFalse ?? false) || true); // Evaluates to `True`

Thanks in advance for any insight into this question.

CodePudding user response:

Take a look at the table here: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/#operator-precedence

The operator precedence of the null-coalescing operator ?? is lower than the conditional or operator ||.

This means your code is being evaluated as:

Console.WriteLine(nullableBoolEqualFalse ?? (false || true));

false || true evaluates to true, and nullableBoolEqualFalse ?? true evaluates to nullableBoolEqualFalse which is why you are seeing false in the output.

CodePudding user response:

The reason that the second line evaluates to False is because it compiles to the following:

Console.WriteLine(!flag.HasValue || flag.GetValueOrDefault());

If you print the following two statements:

Console.WriteLine(!nullableBoolEqualFalse.HasValue);
Console.WriteLine(nullableBoolEqualFalse.GetValueOrDefault());

the first will evaluate to false (because it takes the inverse of flag.HasValue and it has a value), meaning that it will then evaluate .GetValueOrDefault(), which, in this case, has the value of false.

  • Related