Skip to content

Latest commit

 

History

History
72 lines (46 loc) · 4.94 KB

LDM-2024-08-26.md

File metadata and controls

72 lines (46 loc) · 4.94 KB

C# Language Design Meeting for August 26th, 2024

Agenda

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: #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 readonlyness 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.