Champion: Target-typed switch expression (16.3, Core 3)
- Dominant language
- C#
- Stars
- 12.7k
- Forks
- 1.1k
- Avg merge
- 11h 1m
- Merged PRs (30d)
- 3
Description
- [X] Proposal added (below)
- [x] Discussed in LDM 2019-04-22
- [X] Decision in LDM (Approved for C# 8)
- [ ] Finalized (done, rejected, inactive)
- [ ] Spec'ed
@333fred asked me
> Given the following code, we cannot determine a best type for the switch expression and the code does not compile. Why can't we determine that the best type is `A`, given that's the target type of the expression?
>
> ``` c#
> class A
> {
> }
>
> class B : A
> {
> }
>
> class C : A
> {
> }
>
> class D
> {
> void M()
> {
> A a = null;
> a = a switch
> {
> B b => b,
> C c => c,
> _ => throw new System.Exception(),
> };
> }
> }
> ```
>
> Casting one branch to `A` fixes the code
My initial reaction was
> We use the same inference algorithm for `new []{ b, c }` and `() => { if (b) return b; else return c; }` and `c ? b : c` and `M(b, c)` where `T M(T x, T y)`. The general philosophy is that we avoid inferring a type that wasn't one of the input types. What if they had a common interface but not a common base class? What if they had two common interfaces? We just don't do that. We use "target type" only for certain conversions. We don't have a "conversion from array creation" or "conversion from conditional expression" and similarly we won't have a "conversion from switch expression".
However, my answer was not satisfactory to either @333fred or myself.
This is a proposal to "do that".
### Proposal
Currently, a switch expression is specified to have a type that is the inferred common type of the expressions in the switch arms. It is (currently) required that there be such a common type.
Instead, I propose
1. We attempt to infer a common type among the arms of the switch expression. If there is such a common type, that is the (natural) type of the switch expression.
2. There is a *switch expression conversion* (a new implicit conversion-from-expression) from a switch expression to the type `T` if there is an implicit conversion from every arm's value expression to `T`.
3. Let `T` be the type of the switch expression, either the target type of the *switch expression conversion*, or if it was not subject to such a conversion the expression's natural type. It is an error if `T` does not exist. It is an error if a switch arm's expression cannot be implicitly converted to `T`.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.