# C# Language Design Meeting for August 26th, 2024

## Agenda

- [`field` keyword open questions](#field-keyword-open-questions)
    - [`field` in property initializers](#field-in-property-initializers)
    - [Interaction with partial properties](#interaction-with-partial-properties)
    - [`readonly` field](#readonly-field)

## Quote of the Day

- "Whenever I want to thumbs up, I see the open hand and I click it"

## Discussion

### `field` keyword open questions

Champion issue: https://github.com/dotnet/csharplang/issues/140  
Spec: https://github.com/dotnet/csharplang/blob/ce7bd40ee26432ba085c5ba9d8ad3be6d4f7fa9a/proposals/field-keyword.md#open-ldm-questions

#### `field` in property initializers

https://github.com/dotnet/csharplang/blob/ce7bd40ee26432ba085c5ba9d8ad3be6d4f7fa9a/proposals/field-keyword.md#field-in-property-initializer

We started by looking at whether `field` should be visible in the property initializer. This would diverge in behavior from how `this` is generally inaccessible in accessors,
and most of our debate centered not around whether we should disallow this, but whether we should have a specific error if the user does try to do this. Ultimately, we decided
to let the compiler implementation decide whether to have a specific error, but to otherwise not adjust the behavior. If there is an actual class field named `field`, then it
will be visible in the initializer (and potentially be an error to reference); in all cases, the synthesized backing field of the property will not be visible.

##### Conclusion

We will bind the initializer as in previous versions of C#. We won't put the backing field in scope, nor will we prevent referencing other members named `field`.

#### Interaction with partial properties

https://github.com/dotnet/csharplang/blob/ce7bd40ee26432ba085c5ba9d8ad3be6d4f7fa9a/proposals/field-keyword.md#interaction-with-partial-properties

Next, we thought about how partial properties and `field` should interact. There's two main interactions to consider: where to allow initializers, and whether to allow auto-implemented
accessors in the implementation side of the property.

For the first question, we considered the use cases for partial `field`-backed properties. We foresee most of these properties being used by source generators, in one of two possible ways:

1. A hint to a source generator (likely combined with an attribute) that the generator should implement the body of this property.
2. A hint from a source generator to the user that the machinery of the generator requires the user to write a property; using a partial property here would give the user a better
   error than "undefined member `Name`", and convey to the user the shape of what they need to implement.

In both scenarios, it is useful for the user to be able to put an initializer on the property to indicate what the backing field should be initialized to. We are also in agreement
that we don't want to try and allow putting the initializer in both locations, even if it is semantically identical; attempting to determine whether the initializers are identical
is difficult for both the compiler and a human reading the code. Thus, we conclude that initializers will be allowed on either the declaration or the implementation, but not both
at the same time.

For the second question, we again thought about our example scenarios; the scenarios are generally locations where one or both of the accessors can't just be a simple auto-accessor.
They need to have some kind of side effect, such as triggering an INPC notification, logging, etc. However, we _do_ think that the "only one accessor is complex" scenario is common
enough to allow one of the implementing accessors to be an auto-implemented accessor. Allowing both accessors to be automatically implemented is not currently on the table, as it's
complex for the compiler to implement and we don't have any scenarios to drive the design.

##### Conclusion

Either declaring or implementing property locations can use an initializer, but not both at the same time. At least one implementing accessor must be manually implemented, but the
other accessor can be automatically implemented.

#### `readonly` field

https://github.com/dotnet/csharplang/blob/ce7bd40ee26432ba085c5ba9d8ad3be6d4f7fa9a/proposals/field-keyword.md#readonly-field

Our final question today is around the `readonly`ness of the backing field. This is mostly unobservable; reflection can see it, but it doesn't have a real impact on user code. Given
the lack of observability, we think the right decision is to rely on the containing context; if the containing type or property is `readonly`, then the backing field will be too.
Practically, this means that when the containing type is a `struct`, and either it or the property is marked `readonly`, then the synthesized backing field will also be `readonly`.

##### Conclusion

When the containing type is a `struct`, and either it or the property is marked `readonly`, then the synthesized backing field will also be `readonly`.
