Craig Selbert
Craig Selbert

Reputation: 777

C#: Null coalescing operator using nullable bool giving (what I consider) incorrect result

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.

Upvotes: 2

Views: 690

Answers (2)

David L
David L

Reputation: 33815

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.

Upvotes: 0

E. Moffat
E. Moffat

Reputation: 3288

Take a look at the table here: https://learn.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.

Upvotes: 7

Related Questions