- "Wouldn't infinite productivity be subject to a Poisson distribution?" "I gave up on my math degree years ago"
#140
https://github.com/dotnet/csharplang/blob/6501263ca17173262ecb4449c4977b28a28cc375/proposals/semi-auto-properties.md#open-ldm-questions
We looked at a few open questions in field
today with fresh eyes, now that we made adjustments to
how definite assignment works in structs. In particular, we want to make sure that,
given the adjustments made to when structs are definitely assigned, our previous decisions make sense.
Previously we'd stated:
We have the following formalized rule for when initializers are permitted:
- Initializers are permitted when a property has a backing field that will be emitted and the property either does not have a setter, or its setter is auto-implemented.
We have the following rule for when properties can be assigned in the constructor of a type:
- Properties can be assigned in the constructor of a type if that property has a setter, or is a get-only property whose backing field will be emitted.
Both of these rules are being re-examined today.
In addition to re-examining our initializer rule in light of struct definite assignment, we also wanted to consider community feedback, which we received a small amount of. In particular, the feedback was concerned that we were ruling out defaults for INPC or other similar scenarios. After some thought, we agreed with this feedback, and think that with how we've structured the definite assignment rule, we can come up with a simple rule that is just as easy to explain, if not necessarily as obvious to a reader:
- Initializers are permitted for any property with a backing field. The initializer always assigns directly to the backing field.
We are concerned that this rule will be something learned, rather than something taught. We can potentially improve compiler tooling for error initializer scenarios, but, in records in particular, there is some potential concern that this will be stumbled onto by accident, rather than intentionally. For example, there could be confusion about what this code does:
new Rec(-1);
record struct Rec(int Item)
{
public int Item { get; set => value < 0 ? throw new Exception() : field = value; } = Item;
}
This will assign Item
directly to the backing field and not run the initializer, and no exception will be thrown. Despite this, we're hesitantly
ok with moving forward with the design.
The following rule is accepted:
- Initializers are permitted for any property with a backing field. The initializer always assigns directly to the backing field.
With the updated rules for definite assignment, the change is relatively straight forward. A semi-auto-property will be treated as a regular auto
property for the purposes of calculating default
backing field initialization if its setter/initer is automatically implemented, or if it
does not have a setter or initer.
As above.