- Proposed
- Prototype: None
- Implementation: None
- Specification: See below
There is a situation in which the current common-type algorithm results are counter-intuitive, and results in the programmer adding what feels like a redundant cast to the code. With this change, an expression such as condition ? 1 : null
would result in a value of type int?
, and an expression such as condition ? x : 1.0
where x
is of type int?
would result in a value of type double?
.
This is a common cause of what feels to the programmer like needless boilerplate code.
We modify the specification for finding the best common type of a set of expressions §11.6.3.15 to affect the following situations:
- If one expression is of a non-nullable value type
T
and the other is a null literal, the result is of typeT?
. - If one expression is of a nullable value type
T?
and the other is of a value typeU
, and there is an implicit conversion fromT
toU
, then the result is of typeU?
.
This is expected to affect the following aspects of the language:
- the ternary expression §11.15
- implicitly typed array creation expression §11.7.15.5
- inferring the return type of a lambda §11.6.3.13 for type inference
- cases involving generics, such as invoking
M<T>(T a, T b)
asM(1, null)
.
More precisely, we change the following sections of the specification (insertions in bold, deletions in strikethrough):
An output type inference is made from an expression
E
to a typeT
in the following way:
- If
E
is an anonymous function with inferred return typeU
(§11.6.3.13) andT
is a delegate type or expression tree type with return typeTb
, then a lower-bound inference (§11.6.3.10) is made fromU
toTb
.- Otherwise, if
E
is a method group andT
is a delegate type or expression tree type with parameter typesT1...Tk
and return typeTb
, and overload resolution ofE
with the typesT1...Tk
yields a single method with return typeU
, then a lower-bound inference is made fromU
toTb
.- **Otherwise, if
E
is an expression with nullable value typeU?
, then a lower-bound inference is made fromU
toT
and a null bound is added toT
. **- Otherwise, if
E
is an expression with typeU
, then a lower-bound inference is made fromU
toT
.- Otherwise, if
E
is a constant expression with valuenull
, then a null bound is added toT
- Otherwise, no inferences are made.
An unfixed type variable
Xi
with a set of bounds is fixed as follows:
- The set of candidate types
Uj
starts out as the set of all types in the set of bounds forXi
.- We then examine each bound for
Xi
in turn: For each exact boundU
ofXi
all typesUj
which are not identical toU
are removed from the candidate set. For each lower boundU
ofXi
all typesUj
to which there is not an implicit conversion fromU
are removed from the candidate set. For each upper boundU
ofXi
all typesUj
from which there is not an implicit conversion toU
are removed from the candidate set.- If among the remaining candidate types
Uj
there is a unique typeV
from which there is an implicit conversion to all the other candidate types, thenXi
is fixed toV
.
- If
V
is a value type and there is a null bound forXi
, thenXi
is fixed toV?
- Otherwise
Xi
is fixed toV
- Otherwise, type inference fails.
There may be some incompatibilities introduced by this proposal.
None.
- What is the severity of incompatibility introduced by this proposal, if any, and how can it be moderated?
None.