- "Maybe we should renumber that list so we're not confused? I know we're all programmers, but 0-based is confusing here." "We're all programmers, but VB programmers at heart."
For solving this issue, we generated the following ideas:
- No change to the behavior, and document it. We don't really think this is tenable, but it is technically an option.
- Report an error calling
: this()
when field initializers are present andthis()
is a default parameterless constructor. - No error; zero fields after running initializers (silent breaking change to existing code).
- No error, zero fields before running initializers.
- Option #4 for now (C# 10), then #2 later.
- Option #4 for now (C# 10), add a warning wave later on uses of
: this()
ornew S()
when there is no user-defined parameterless constructor.
Several LDM members immediately felt that 4 was the correct option, and did what they were expecting the code to do. However, it does carry with it the potential for
confusion around what calling the parameterless constructor does: for a struct with no parameterless constructor with field initializers, the behavior of : this()
and of new S()
will appear to differ. We may specify that field initializers run in a different order, but the perception will likely be different. Option 2 would
be a consistent way of correcting this perception issue: either make the behavior between all references to a parameterless constructor identical, or forbid calling a
parameterless constructor where behavior would be confusing. However, while this option is most in line with C# of the past, we are already planning on making big
changes to struct initialization in C# 11, and this behavior would have the unfortunate behavior of punishing any user that adds a field initializer to existing structs
that already use : this()
in places.
We're also concerned about a warning wave here, as there are plenty of uses of : this()
as a struct initializer that are perfectly fine today that would become
warnings if we took a hard line stance here. It might be better to approach such a ruling a code style thing: the IDE can gray out the : this()
initializer in C# 11,
and fixers can remove dead code as they do today.
We will adopt option 4 for C# 10, and look into code style analyzers and IDE experiences to remove potentially confusing and redundant use of : this()
in C# 11.
We looked at another turn of the crank in the proposal around file private
. The proposal today goes for a very integrated approach, adding a new accessibility modifier
and rationalizing its existence with other accessibilities, paring the accessibilities that can be combined with file
down to a small set. Through discussion, we
arrived at 3 proposal options:
- #5969 as is.
file
orfileonly
as a new accessibility. It cannot be combined with other accessibilities, and means only "can be accessed in this file".file
is allowed to be combined with any existing accessibility. Everything works exactly as it does today, but whenfile
is applied, the name is not in scope outside the current file.
We think that option 1 has the potential to be complicated. Both 2 and 3 are relatively simple to explain, with 2 being the simpler of them. Option 1 limits and changes
existing rules when file
is applied, which starts to need a decoder ring to understand.
We're equally split between option 2 and 3 at this point. We need to explore these a bit more with a smaller group, clarify the motivating scenarios for the feature, and come back soon for another session.