[Proposal]: Implicit primary constructors #9189
Unanswered
McChoc
asked this question in
Language Ideas
Replies: 1 comment
-
I'm pretty sure a variant of syntax like this was proposed when primary constructors were first being designed. IMO, they're not clearer. They hide a critical aspect of the contract within the class body which would be very easy to miss. An innocuous refactor such as reordering members would also incur breaking changes as it would impact the order of parameters to the constructor, not to mention the problem if said members are split between multiple |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
This proposal aims to improve the readability and flexibility of primary constructors by moving their parameters from the class declaration to the class body. The contextual keywords
param
,params
andbase
would be allowed in front of fields, properties, and events to initialize them from an implicit primary constructor.Motivation
C# 12 introduced primary constructors, which help reduce boilerplate constructor code. However, they have two major drawbacks:
They have limited flexibility
The parameters of primary constructors are stored as mutable private fields. They cannot be public, they cannot be properties or events and, most importantly, they cannot be
readonly
.They clutter the class declaration
If a class has multiple primary constructor parameters that are passed to the base constructor, the class declaration can become hard to read. Formating all these parameters and arguments is not intuitive. The issue is even worse if the class implements a number of interfaces and has generic type constraints.
This proposal addresses both issues by moving constructor parameters from the class declaration to the class body while maintaining the benefits of primary constructors.
Syntax
Current C# 12 Primary Constructor Syntax
Proposed Implicit Primary Constructor Syntax
The
param
contextual keyword declares an implicit constructor where each marked member acts as both a parameter and a field/property/event. This approach eliminates clutter from the class declaration and, since the parameters are now members, they can have any access modifier, bereadonly
, or even be properties or events. The order of theparam
members in the class body determines the order of the constructor parameters.Implicit primary constructors would be an alternative to standard primary constructors, behaving similarly. Implicit primary constructors would always be public and if one is defined, all other constructors must call it using a
this()
constructor invocation.params
modifierThe
params
modifier would allow aparam
member to accept a variable number of arguments. Theparams
modifier would replaceparam
, as having both would be redundant. Only oneparams
member is allowed per class and noparam
members should be declared after theparams
member.ref
fieldsSince a by-reference variable cannot be initialized with a value, if the
param
modifier is applied to aref
field, the implicit parameter would have to beref
as well. So, aparam ref
field would mean that both the implicit parameter and the field would have theref
modifier applied to them.Equivalent to:
Base constructors
If a class using an implicit primary constructor needs to pass arguments to a base constructor, the
base
keyword can be placed in front of theparam
orparams
modifier to specify that this parameter must be forwarded to the base constructor.The order of the
base param
members must match the order of the parameters of the base constructor. If there are multiple base constructors the order and types of thebase param
members is what will determine which constructor is called.Using this syntax should still enforce the standard execution order. This means that the base constructor should be called with the values passed to
base param
members before any value is assigned to any member.Default values
Giving a
param
member an initial value by using the assignment operator would be useless since they will be assigned a value by the implicit constructor anyway. However, the syntax could still be used to define optional parameters for the implicit primary constructor. Optionalparam
members must come after all requiredparam
members, but before theparams
member if any.params
members cannot have default values.Attributes
To add an attribute on an implicit primary constructor, you would use the
method
target.To add an attribute on the implicit parameter of a
param
member, you would use theparam
target.Limitations
param
members separated in multiple class bodies would make this order ambiguous. Therefore, only a single partial class body may haveparam
members.param
andrequired
. Only one initilization method should be chosen.param
modifier would only be allowed if they are auto-implemented.param
members act as parameters, thein
andout
modifiers would not be allowed on them.Conclusion
This proposal improves primary constructors by providing more flexibility regarding how the parameters are implemented. It allows them to be implemented as either fields, properties or events. It allows them to be
readonly
or not. And it allows them to have any accessibility modifier. The proposal also improves readability by moving the parameters of primary constructors from the class definition to the class body.Beta Was this translation helpful? Give feedback.
All reactions