target-typed new: reflect LDM decisions 2020-03-25 (#3311)

This commit is contained in:
Neal Gafter 2020-03-25 15:40:49 -07:00 committed by GitHub
parent 23172a7c6d
commit 64da1dcf00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -47,15 +47,11 @@ target_typed_new
;
```
A *target_typed_new* expression does not have a type. However, there is a new *object creation conversion* that is an implicit conversion from expression, that exists from a *target_typed_new* to every type. It is an error for this conversion to be applied unless the type being converted to is
- a `struct` type; or
- a `class` type that is not an anonymous type; or
- a `delegate` type; or
- a type parameter.
A *target_typed_new* expression does not have a type. However, there is a new *object creation conversion* that is an implicit conversion from expression, that exists from a *target_typed_new* to every type.
Given a target type `T`, the type `T0` is `T`'s underlying type if `T` is an instance of `System.Nullable`. Otherwise `T0` is `T`. The meaning of a *target_typed_new* expression that is converted to the type `T` is the same as the meaning of a corresponding *object_creation_expression* that specifies `T0` as the type.
It is a compile-time error if a *target_typed_new* is used as an operand of a unary or binary operator.
It is a compile-time error if a *target_typed_new* is used as an operand of a unary or binary operator, or if it is used where it is not subject to an *object creation conversion*.
> **Open Issue:** should we allow delegates and tuples as the target-type?
@ -64,7 +60,7 @@ The above rules include delegates (a reference type) and tuples (a struct type).
(int a, int b) t = new(1, 2); // "new" is redundant
Action a = new(() => {}); // "new" is redundant
(int a, int b) t = new(); // ruled out by "use of struct default constructor"
(int a, int b) t = new(); // OK; same as (0, 0)
Action a = new(); // no constructor found
```
@ -77,10 +73,11 @@ The following are consequences of the specification:
- It is disallowed when there is no type to target: unary operators, collection of a `foreach`, in a `using`, in a deconstruction, in an `await` expression, as an anonymous type property (`new { Prop = new() }`), in a `lock` statement, in a `sizeof`, in a `fixed` statement, in a member access (`new().field`), in a dynamically dispatched operation (`someDynamic.Method(new())`), in a LINQ query, as the operand of the `is` operator, as the left operand of the `??` operator, ...
- It is also disallowed as a `ref`.
- The following kinds of types are not permitted as targets of the conversion
- **Enum types:** not all enum types contain the constant zero, so it should be desirable to use the explicit enum member. It is a compile-time error if a *target_typed_new* is used as an operand of a unary or binary operator.
- **Interface types:** this is a niche feature and it should be preferable to explicitly mention the type.
- **Enum types:** `new()` will work (as `new Enum()` works to give the default value), but `new(1)` will not work as enum types do not have a constructor.
- **Interface types:** This would work the same as the corresponding creation expression for COM types.
- **Array types:** arrays need a special syntax to provide the length.
- **dynamic:** we don't allow `new dynamic()`, so we don't allow `new()` with `dynamic` as a target type.
- **dynamic:** we don't allow `new dynamic()`, so we don't allow `new()` with `dynamic` as a target type.
- **tuples:** These have the same meaning as an object creation using the underlying type.
- All the other types that are not permitted in the *object_creation_expression* are excluded as well, for instance, pointer types.
## Drawbacks
@ -107,3 +104,4 @@ Most of complaints about types being too long to duplicate in field initializati
- [LDM-2018-06-25](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-06-25.md)
- [LDM-2018-08-22](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-08-22.md#target-typed-new)
- [LDM-2018-10-17](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-10-17.md)
- [LDM-2020-03-25](https://github.com/dotnet/csharplang/blob/master/meetings/2020/LDM-2020-03-25.md)