You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: proposals/readonly-setter-calls-on-non-variables.md
+44-32Lines changed: 44 additions & 32 deletions
Original file line number
Diff line number
Diff line change
@@ -126,27 +126,48 @@ The current v8 specification draft does not yet specify readonly members (<https
126
126
127
127
> When a property or indexer declared in a _struct_type_ is the target of an assignment, **either** the instance expression associated with the property or indexer access shall be classified as a variable, **or the set accessor of the property or indexer shall be a readonly member ([§16.2.2](https://github.com/dotnet/csharpstandard/blob/standard-v7/standard/structs.md#1622-struct-modifiers))**. If the instance expression is classified as a value **and the set accessor is not a readonly member**, a binding-time error occurs.
128
128
129
-
## Expansions
129
+
## Downsides
130
+
131
+
If this proposal is taken, it becomes a source-breaking change to remove the `readonly` keyword from a struct or setter. Without the `readonly` keyword, the errors would then be relevant and would reappear.
130
132
131
-
There's another location where this kind of assignment is blocked, which is in object initializers:
133
+
Due to what looks like an unintentional change in the compiler, this source-breaking change is already in effect when the setter is called on an invocation expression:
132
134
133
135
```cs
134
-
// ❌ CS1918 Members of property 'C.ArraySegmentProp' of type 'ArraySegment<object>' cannot be assigned with an object
// Removing 'readonly' from S2.Prop.set causes a CS1612 error.
149
+
M().Prop=1;
150
+
151
+
S2M() =>default;
152
+
153
+
publicstructS2
154
+
{
155
+
publicintProp { get=>0; readonly set { } }
142
156
}
143
157
```
144
158
145
-
For the same reasons as above, this error is unnecessary when the properties being initialized have readonly `set`/`init` accessors. The error could be made more granular, placed on each property initializer which calls a _non-readonly_ setter.
159
+
## Answered LDM questions
160
+
161
+
### Should similar assignments be permitted in object initializers?
146
162
147
-
Even in the limited cases where a ref-returning indexer is applicable, it does not help with CS1918, where it still unnecessarily broad:
163
+
There's a separate error, CS1918 that blocks assignments through readonly setters when the assignments appear in object initializers. In addition, this error even blocks assignments to ref-returning properties and indexers, and those assignments are not blocked when they appear outside of object initializers.
148
164
149
165
```cs
166
+
// ❌ CS1918 Members of property 'C.ArraySegmentProp' of type 'ArraySegment<object>' cannot be assigned with an object
If this proposal is taken, it becomes a source-breaking change to remove the `readonly` keyword from a struct or setter. Without the `readonly` keyword, the errors would then be relevant and would reappear.
165
-
166
-
Due to what looks like an unintentional change in the compiler, this source-breaking change is already in effect when the setter is called on an invocation expression:
183
+
Such assignments desugar to the following form, the same form in which the CS1612 warning is being removed:
167
184
168
185
```cs
169
-
// Removing 'readonly' from S1 causes a CS1612 error.
170
-
M().Prop=1;
171
-
172
-
S1M() =>default;
173
-
174
-
publicreadonlystructS1
175
-
{
176
-
publicintProp { get=>0; set { } }
177
-
}
186
+
vartemp=newC();
187
+
// Warning being removed:
188
+
// CS1612 Cannot modify the return value of 'C.ArraySegmentProp' because it is not a variable
189
+
temp.ArraySegmentProp[42] =newobject();
178
190
```
179
191
180
192
```cs
181
-
// Removing 'readonly' from S2.Prop.set causes a CS1612 error.
Should this check be made more granular, so that members of struct types may be assigned when they would be allowed to be assigned in the desugared form?
185
199
186
-
publicstructS2
187
-
{
188
-
publicintProp { get=>0; readonly set { } }
189
-
}
190
-
```
200
+
#### Answer
201
+
202
+
Yes. This expansion will be included. [(LDM 2025-04-02)](https://github.com/dotnet/csharplang/blob/main/meetings/2025/LDM-2025-04-02.md#expansions)
0 commit comments