Avoid synthesizing a parameterless constructor for struct
types; run field initializers from declared constructors only;
and report an error if the struct
declaration includes field initializers but no constructors.
With C#10, if a struct
type declaration includes field initializers but no constructors, the compiler will synthesize a parameterless constructor that will run the field initializers.
The compiler does not synthesize a parameterless constructor if there are explicit constructors because,
with record struct
types, the field initializers are bound in the context of the primary constructor so the synthesized parameterless constructor would need to invoke the primary constructor to run the field initializers. But what values should be passed for the primary constructor arguments?
The fact that a parameterless constructor is synthesized in some cases but not all makes it difficult to understand when new()
is equivalent to default
, and it means the result of new()
can change silently when non-default constructors are added or removed.
// With no constructors struct S { public int Value = 42; } WriteLine(new S().Value); // 42
// After adding non-default constructor struct S { public int Value = 42; public S(string message) { } } WriteLine(new S().Value); // 0
If instead, struct
constructors are never synthesized, then the behavior is simplified:
struct
type declares a parameterless constructor, new()
is equivalent to default
, consistent with C#9 and before.Never synthesize a parameterless constructor for struct
types.
Report an error if a struct
type declaration includes field initializers but no explicit constructors.
// With no constructors struct S { public int Value = 42; // error: containing type 'S' has no declared constructor } WriteLine(new S().Value); // error above
// After adding parameterless constructor struct S { public int Value = 42; public S() { } } WriteLine(new S().Value); // 42
// After adding non-default constructor instead struct S { public int Value = 42; public S(string message) { } } WriteLine(new S().Value); // 0Drawbacks
It is a breaking change from C#10 to require an explicit constructor if there are field initializers, but it's not a silent break (an error is reported), and the fix is simple (add an empty parameterless constructor).
Alternatives Unresolved questions Design meetingsRikkiGibson, MauNguyenVan, xiety, Therzok, viktor-svub and 1 more
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4