# C# Language Design Notes for Jan. 16th, 2019 ## Agenda 1. Shadowing in lambdas 2. pattern-based disposal in `await foreach` ## Discussion ### Shadowing in nested functions *Q: Allow shadowing for all lambdas as well?* **A**: Yes. *Q: Allow shadowing with range variables in LINQ queries?* ```C# // char c; var q = from c in s from c2 in s where c != ' ' select c; var q2 = s .SelectMany(c => s, (c, c2) => new { c, c2 }) .Where(_x => _x.c != ' ') .Select(_x => _x.c); ``` `c` and `c2` can't be named the same because they are equivalent to two parameters being named the same. However, should the new `c` be able to shadow the local `c`? **A**: Let's look at the implementation and decide based on the complexity. ### Pattern-based disposal in `await foreach` `WithCancellation` and `ConfigureAwait` both return a custom type that does not implement the interface, just the pattern. `await foreach` does not pick it up because it does not have pattern-based disposal and the type cannot implement the `IAsyncDisposable` type because it does not produce a `ValueTask` return for disposal. Proposals: 1. Just allow pattern-based disposal for `IAsyncDisposable`. Only allow pattern-based disposable for `IDisposable` in ref structs. a. For `await foreach`, use the pattern, then dynamically check for interface and use it if present. b. For `await foreach`, use the pattern, then statically check for the interface and use it if present. The dynamic check in (1a) is used because in C# 1.0 the non-generic `IEnumerator` did not implement IDisposable. The next question is whether to consider extension methods. The standard pattern we've previously settled on is: 1. Check for pattern 2. Check for interface 3. Check for extension methods Can we use this pattern for `IAsyncDisposable`? The primary question is whether to consider extension methods. **Conclusion** Let's do 1b. We do not have a non-generic `IAsyncEnumerator` that doesn't implement `IAsyncDisposable`, so the dynamic check is unnecessary. We will not consider extension methods for `IAsyncDisposable` or `IDisposable` (on ref structs). We will consider extension methods for `IAsyncEnumerable` and `IEnumerable`.