Why are readonly fields able to be assigned in init
accessors but not in with
expressions?
#5019
Replies: 4 comments 8 replies
-
The decision to only relax the limitation for init accessors and not for readonly fields was deliberate. I do not think it is a runtime limitation. It's possible that a sufficiently compelling use case exists to allow this. We'd have to search the proposals and meeting notes for records and init accessors. |
Beta Was this translation helpful? Give feedback.
-
I would like there to be a conceptual equivalence between |
Beta Was this translation helpful? Give feedback.
-
To me, |
Beta Was this translation helpful? Give feedback.
-
Nested types poke a hole in the concept that people should be able to think of record C
{
private readonly int readonlyField;
private int InitOnlyProperty { get; init; }
class NestedType
{
void M()
{
// Since C# 1, readonly fields of containing types cannot be assigned inside nested types even though private
// properties can. This is a difference between readonly fields and private init properties that should
// remain.
// ❌ CS0191 A readonly field cannot be assigned to (except in a constructor or init-only setter of the type
// in which the field is defined or a variable initializer)
// ↓↓↓↓↓↓↓↓↓↓↓↓↓
_ = new C() with { InitOnlyProperty = 1, readonlyField = 1 };
// ↓↓↓↓↓↓↓↓↓↓↓↓↓
_ = new C { InitOnlyProperty = 1, readonlyField = 1 };
}
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
It's keeping me from being able to move classes to records, because I'm having a hard time stomaching the idea of replacing all readonly fields (or all the ones that need it) with
private int a { get; init; }
-style properties.And yet the compiler is happy with this:
If there is a logical difference between these two things, what is it?
Is this a runtime limitation? If so, would the C# team consider a proposal to enable initializing readonly fields in
with
expressions by synthesizing private unspeakable accessors to do the job, like I did manually in the previous code snippet?Beta Was this translation helpful? Give feedback.
All reactions