- 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 to affect the following situations:
- If one expression is of a non-nullable value type
Tand 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 fromTtoU, then the result is of typeU?.
This is expected to affect the following aspects of the language:
- the ternary expression
- implicitly typed array creation expression
- inferring the return type of a lambda 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
Eto a typeTin the following way:
- If
Eis an anonymous function with inferred return typeU(Inferred return type) andTis a delegate type or expression tree type with return typeTb, then a lower-bound inference (Lower-bound inferences) is made fromUtoTb.- Otherwise, if
Eis a method group andTis a delegate type or expression tree type with parameter typesT1...Tkand return typeTb, and overload resolution ofEwith the typesT1...Tkyields a single method with return typeU, then a lower-bound inference is made fromUtoTb.- **Otherwise, if
Eis an expression with nullable value typeU?, then a lower-bound inference is made fromUtoTand a null bound is added toT. **- Otherwise, if
Eis an expression with typeU, then a lower-bound inference is made fromUtoT.- Otherwise, if
Eis a constant expression with valuenull, then a null bound is added toT- Otherwise, no inferences are made.
An unfixed type variable
Xiwith a set of bounds is fixed as follows:
- The set of candidate types
Ujstarts out as the set of all types in the set of bounds forXi.- We then examine each bound for
Xiin turn: For each exact boundUofXiall typesUjwhich are not identical toUare removed from the candidate set. For each lower boundUofXiall typesUjto which there is not an implicit conversion fromUare removed from the candidate set. For each upper boundUofXiall typesUjfrom which there is not an implicit conversion toUare removed from the candidate set.- If among the remaining candidate types
Ujthere is a unique typeVfrom which there is an implicit conversion to all the other candidate types, thenXiis fixed toV.
- If
Vis a value type and there is a null bound forXi, thenXiis fixed toV?- Otherwise
Xiis 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.