Update target-typed-new.md (#1989)
This commit is contained in:
parent
cc9cb6eae6
commit
a6c38525c2
|
@ -20,14 +20,17 @@ Dictionary<string, List<int>> field = new() {
|
||||||
{ "item1", new() { 1, 2, 3 } }
|
{ "item1", new() { 1, 2, 3 } }
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
Allow omitting the type when it can be inferred from usage.
|
Allow omitting the type when it can be inferred from usage.
|
||||||
```cs
|
```cs
|
||||||
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
|
XmlReader.Create(reader, new() { IgnoreWhitespace = true });
|
||||||
```
|
```
|
||||||
|
|
||||||
Instantiate an object without spelling out the type.
|
Instantiate an object without spelling out the type.
|
||||||
```cs
|
```cs
|
||||||
private readonly static object s_syncObj = new();
|
private readonly static object s_syncObj = new();
|
||||||
```
|
```
|
||||||
|
|
||||||
## Detailed design
|
## Detailed design
|
||||||
[design]: #detailed-design
|
[design]: #detailed-design
|
||||||
|
|
||||||
|
@ -38,14 +41,15 @@ object_creation_expression
|
||||||
| 'new' type object_or_collection_initializer
|
| 'new' type object_or_collection_initializer
|
||||||
;
|
;
|
||||||
```
|
```
|
||||||
|
|
||||||
A target-typed `new` is convertible to any type. As a result, it does not contribute to overload resolution. This is mainly to avoid unpredictable breaking changes.
|
A target-typed `new` is convertible to any type. As a result, it does not contribute to overload resolution. This is mainly to avoid unpredictable breaking changes.
|
||||||
|
|
||||||
The argument list and the initializer expressions will be bound after the type is determined.
|
The argument list and the initializer expressions will be bound after the type is determined.
|
||||||
|
|
||||||
The type of the expression would be inferred from the target-type which would be required to be one of the following:
|
The type of the expression would be inferred from the target-type which would be required to be one of the following:
|
||||||
|
|
||||||
- **Any struct type**
|
- **Any struct type** (including tuple types)
|
||||||
- **Any reference type**
|
- **Any reference type** (including delegate types)
|
||||||
- **Any type parameter** with a constructor or a `struct` constraint
|
- **Any type parameter** with a constructor or a `struct` constraint
|
||||||
|
|
||||||
with the following exceptions:
|
with the following exceptions:
|
||||||
|
@ -53,10 +57,12 @@ with the following exceptions:
|
||||||
- **Enum types:** not all enum types contain the constant zero, so it should be desirable to use the explicit enum member.
|
- **Enum types:** not all enum types contain the constant zero, so it should be desirable to use the explicit enum member.
|
||||||
- **Interface types:** this is a niche feature and it should be preferable to explicitly mention the type.
|
- **Interface types:** this is a niche feature and it should be preferable to explicitly mention the type.
|
||||||
- **Array types:** arrays need a special syntax to provide the length.
|
- **Array types:** arrays need a special syntax to provide the length.
|
||||||
- **Struct default constructor**: this rules out all primitive types and most value types. If you wanted to use the default value of such types you could write `default` instead.
|
- **dynamic:** we don't allow `new dynamic()`, so we don't allow `new()` with `dynamic` as a target type.
|
||||||
|
|
||||||
All the other types that are not permitted in the *object_creation_expression* are excluded as well, for instance, pointer types.
|
All the other types that are not permitted in the *object_creation_expression* are excluded as well, for instance, pointer types.
|
||||||
|
|
||||||
|
When the target type is a nullable value type, the target-typed `new` will be converted to the underlying type instead of the nullable type.
|
||||||
|
|
||||||
> **Open Issue:** should we allow delegates and tuples as the target-type?
|
> **Open Issue:** should we allow delegates and tuples as the target-type?
|
||||||
|
|
||||||
The above rules include delegates (a reference type) and tuples (a struct type). Although both types are constructible, if the type is inferable, an anonymous function or a tuple literal can already be used.
|
The above rules include delegates (a reference type) and tuples (a struct type). Although both types are constructible, if the type is inferable, an anonymous function or a tuple literal can already be used.
|
||||||
|
@ -67,23 +73,20 @@ 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(); // ruled out by "use of struct default constructor"
|
||||||
Action a = new(); // no constructor found
|
Action a = new(); // no constructor found
|
||||||
|
|
||||||
var x = new() == (1, 2); // ruled out by "use of struct default constructor"
|
### Miscellaneous
|
||||||
var x = new(1, 2) == (1, 2) // "new" is redundant
|
|
||||||
```
|
|
||||||
|
|
||||||
|
`throw new()` is disallowed.
|
||||||
|
|
||||||
> **Open Issue:** should we allow `throw new()` with `Exception` as the target-type?
|
Target-typed `new` is not allowed with binary operators.
|
||||||
|
|
||||||
We have `throw null` today, but not `throw default` (though it would have the same effect). On the other hand, `throw new()` could be actually useful as a shorthand for `throw new Exception(...)`. Note that it is already allowed by the current specification. `Exception` is a reference type, and the specification for the throw statement says that the expression is converted to `Exception`.
|
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, ...
|
||||||
|
|
||||||
> **Open Issue:** should we allow usages of a target-typed `new` with user-defined comparison and arithmetic operators?
|
It is also disallowed as a `ref`.
|
||||||
|
|
||||||
For comparison, `default` only supports equality (user-defined and built-in) operators. Would it make sense to support other operators for `new()` as well?
|
|
||||||
|
|
||||||
## Drawbacks
|
## Drawbacks
|
||||||
[drawbacks]: #drawbacks
|
[drawbacks]: #drawbacks
|
||||||
|
|
||||||
None.
|
There were some concerns with target-typed `new` creating new categories of breaking changes, but we already have that with `null` and `default`, and that has not been a significant problem.
|
||||||
|
|
||||||
## Alternatives
|
## Alternatives
|
||||||
[alternatives]: #alternatives
|
[alternatives]: #alternatives
|
||||||
|
@ -96,6 +99,11 @@ Most of complaints about types being too long to duplicate in field initializati
|
||||||
- Should we forbid usages in expression trees? (no)
|
- Should we forbid usages in expression trees? (no)
|
||||||
- How the feature interacts with `dynamic` arguments? (no special treatment)
|
- How the feature interacts with `dynamic` arguments? (no special treatment)
|
||||||
- How IntelliSense should work with `new()`? (only when there is a single target-type)
|
- How IntelliSense should work with `new()`? (only when there is a single target-type)
|
||||||
|
|
||||||
## Design meetings
|
## Design meetings
|
||||||
|
|
||||||
- [LDM-2017-10-18](https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-10-18.md#100)
|
- [LDM-2017-10-18](https://github.com/dotnet/csharplang/blob/master/meetings/2017/LDM-2017-10-18.md#100)
|
||||||
|
- [LDM-2018-05-21](https://github.com/dotnet/csharplang/blob/master/meetings/2018/LDM-2018-05-21.md)
|
||||||
|
- [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)
|
||||||
|
|
Loading…
Reference in a new issue