Assigning bool? to bool

.net, c#, compiler-construction, nullable

Solution

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`.

Problem

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`?

Original source