# C# Language Design Meeting for February 15th, 2023

## Agenda

- [Open questions in primary constructors](#open-questions-in-primary-constructors)
    - [Capturing parameters in lambdas](#capturing-parameters-in-lambdas)
    - [Assigning to `this` in a `struct`](#assigning-to-this-in-a-struct)


## Quote of the Day

- "Where did you think we put that? Magic?"

## Discussions

### Open questions in primary constructors

https://github.com/dotnet/csharplang/issues/2691  
https://github.com/dotnet/csharplang/blob/2867220fe142dfefd47d8cb20fb88393e4156059/proposals/primary-constructors.md#open-questions

#### Capturing parameters in lambdas

We first considered the question of what happens when a lambda in a field or property initializer captures a parameter that is also captured by the containing type. For example:

```cs
partial class C1
{
    public System.Func<int> F1 = Execute1(() => p1++); // Capture 1
}

partial class C1 (int p1)
{
    public int M1() { return p1++; } // Capture 2
    static System.Func<int> Execute1(System.Func<int> f)
    {
        _ = f();
        return f;
    }
}
```

To follow standard capture rules, both `p1`s will need to refer to the same storage location, and observe the changes from one to the other. There's really two questions here:
first, should we allow this at all? And second, how will we implement it (and do any implementation strategies have semantic implications)?

For the first question, we started by thinking about whether to disallow the scenario where a primary constructor parameter is captured by two locations at once. But we're concerned
about spooky action at a distance here, where adding a field initializer can cause compilation errors in a different location. We also don't think that the issue that the rule was
originally created to avoid is an issue in this area: `this` is not being generally exposed before the base constructor has been run, and there are no changes to virtual members that
can be invoked before the base constructor has run. We therefore lean towards allowing it.

For the second question, we thought about whether to do a double-closure technique, where we create an inner closure type that is then shared between the accesses, or whether to simply
close over `this` in the lambda. After some consideration, we think we're ok with just using `this`, particularly as the double-capture could potentially have some bleed-through effects
on whether an individual type is considered `unmanaged`, and potentially causes allocations that weren't expected. The main issue will be working with the runtime team to ensure that
ILVerify understands the pattern.

##### Conclusion

This scenario is allowed, and we will work with the runtime team to make sure that ILVerify is updated for this scenario.

#### Assigning to `this` in a `struct`

Finally, we looked at whether allowing self-assignment in a struct to silently overwrite primary constructor parameter captures is a good thing, or if we should warn/error/something else
for the scenario. We think that this is the least surprising behavior that this could have, and that it would be more surprising if it didn't have this effect. A warning does not seem
appropriate: either you didn't even know this syntax was possible, or you do know what this syntax means and you were expecting the state of `this` to be overwritten; primary constructor
parameters are part of that state, so they should logically be overwritten.

##### Conclusion

Allowed, no warning.
