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
.