115 lines
No EOL
3.2 KiB
Markdown
115 lines
No EOL
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. |