csharplang/meetings/2019/LDM-2019-01-09.md
2019-01-15 16:09:37 -08:00

115 lines
3.2 KiB
Markdown

# C# Language Design Notes for Jan. 9th, 2019
## Agenda
1. GetAsyncEnumerator signature
2. Ambiguities in nullable array type syntax
2. Recursive Patterns Open Language Issues https://github.com/dotnet/csharplang/issues/2095
## Discussion
### Async streams GetAsyncEnumerator revisited
Discussed over email as well.
Proposal: bind `e.GetAsyncEnumerator()` and use the result, including methods
with optional parameters or `params` and extension methods.
We like the simple bind accepting optional parameters and `params`, but
extension methods are a problem. We have a number of different features that
have backwards compatibility constraints preventing them from preferring extension
methods over interface implementation. In addition, the design of extension methods
is always as a last resort and we prefer code directly from the type (including
interface implementation).
**Conclusion**
Bind a lookup, but without extension methods. After looking for the interface,
consider extension methods. Follow-up issue to deal with the difference with
simple `foreach`, which always looks for a zero-parameter method and doesn't
consider extension methods.
*Q: What about [Caller...] attributes?*
**A**: Let's do what we did for LINQ, which has to do roughly the same thing.
### Obsolete
Do we respect the obsolete attribute in lookups in foreach, async foreach,
and pattern dispose?
**Conclusion**
Yes.
### Ambiguities in nullable array types (again)
Example:
`if (o is string[][]?(var e0, var e1, var e2) s)`
This is now ambiguous because the token after the `?` is not helpful in
resolving the ambiguity.
1. Keep the order, but address using lookahead
2. ? is a type constructor (reverse the order of brackets and question marks)
3. reverse the order of ?'s only
4. Introduce Array<T>
```C#
Array<int[]?>
new Array<int[]?>(3)
new Array<int[]?> { new[] {1}, null, new [] {2, 3 }}
```
5. Don't allow nullability in jagged arrays
**Conclusion**
Let's try (2) and see how it works.
### Should SwitchExpressionException capture an unreified tuple input?
Yes, we think so.
### Rename deconstruct pattern to positional pattern?
Yes. The extra developer work required is worth it.
### Permit trailing comma in a switch expression?
```C#
e switch {
1 => true,
2 => false,
}
```
Yes, permit optional commas anywhere there are curly braces, including
switch expressions, property patterns, etc.
### Warnings for non-nullable fields that are not explicitly initialized
Scenarios that result in unnecessary warnings:
* Initialization helpers called from other constructors
* Factory methods that call constructors
* Object initializers
* Chained constructors
* Set-up/tear-down methods in test frameworks
* Reflection
Options:
0. Do nothing, keep the current behavior
1. Don't track initialization.
2. No warnings for private constructors
3. No warnings for constructors that call methods that might modify `this`
4. Track initialization debt with the class only, reporting warnings at
public entry points.
5. Track initialization debt across classes (and assemblies), reporting
warnings where the object is constructed
**Conclusion**
Let's keep option 0 for now. We're worried about silently hiding legitimate
warnings or that options 4 and 5 are too complicated or expensive to implement.