# 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 ```C# Array new Array(3) new Array { 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.