Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning bool? to bool

Tags:

c#

.net

nullable

Consider the following code:

bool x;
bool? y = null;
x = y?? true;

Assigning a bool? to a bool is a compile-time error, but the above code succeeds both at compile and run-time. Why? Although the 3rd statement ensures we never assign null to x, in case y is not null, we're still assigning a bool? to a bool, so it should be an error from compiler's POV, no?

Or is it that C# compiler is smart enough to find out that a particular piece of code cannot possibly create a situation where a null would be assigned to x?

like image 853
dotNET Avatar asked Nov 15 '25 20:11

dotNET


2 Answers

The type of this expression:

y ?? true

is bool, not bool?.

From section 7.13 of the C# 5 spec:

The type of the expression a ?? b depends on which implicit conversions are available on the operands. In order of preference, the type of a ?? b is A0, A, or B, where A is the type of a (provided that a has a type), B is the type of b (provided that b has a type), and A0 is the underlying type of A if A is a nullable type, or A otherwise. Specifically, a ?? b is processed as follows:

  • If A exists and is not a nullable type or a reference type, a compile-time error occurs.
  • If b is a dynamic expression, the result type is dynamic. At run-time, a is first evaluated. If a is not null, a is converted to dynamic, and this becomes the result. Otherwise, b is evaluated, and this becomes the result.
  • Otherwise, if A exists and is a nullable type and an implicit conversion exists from b to A0, the result type is A0. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0, and this becomes the result. Otherwise, b is evaluated and converted to type A0, and this becomes the result.
  • Otherwise, if A exists and an implicit conversion exists from b to A, the result type is A. At run-time, a is first evaluated. If a is not null, a becomes the result. Otherwise, b is evaluated and converted to type A, and this becomes the result.
  • Otherwise, if b has a type B and an implicit conversion exists from a to B, the result type is B. At run-time, a is first evaluated. If a is not null, a is unwrapped to type A0 (if A exists and is nullable) and converted to type B, and this becomes the result. Otherwise, b is evaluated and becomes the result.
  • Otherwise, a and b are incompatible, and a compile-time error occurs.

In your case, we're in the third bullet:

  • A is bool?
  • A0 is bool
  • B is bool

... so the result type is bool, and you can assign that to a variable of type bool.

like image 198
Jon Skeet Avatar answered Nov 17 '25 09:11

Jon Skeet


In

bool x;
bool? y = null;
x = y?? true;

y ?? true is syntactic sugar for y.HasValue ? y.GetValueOrDefault() : true. So you are really assigning a bool in the compiler's POV. Take a look at the generated IL to see what's happening behind the C# language's features.

Take a look at ILDasm. Playing with it will teach you a lot about the language!

like image 29
dee-see Avatar answered Nov 17 '25 11:11

dee-see



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!