dotnet / dotnet/csharplang

[Proposal]: Readonly setter calls on non-variables

Open
#9,174 0 comments 0 reactions 1 assignee Claimed by @jnm2 View on GitHub
Needs Approved Specification Proposal champion
Dominant language
C#
Stars
12.7k
Forks
1.1k
Avg merge
11h 1m
Merged PRs (30d)
3

Description

# Readonly setter calls on non-variables

* Specification: [proposals/readonly-setter-calls-on-non-variables.md](https://github.com/dotnet/csharplang/blob/main/proposals/readonly-setter-calls-on-non-variables.md)
* Discussion: https://github.com/dotnet/csharplang/discussions/2068

## Summary

Permits a readonly setter to be called on non-variable expressions, and permits object initializers to be used with value types:

```cs
var c = new C();
// Remove the current CS1612 error, because ArraySegment.this is readonly:
c.ArraySegmentProp[10] = new object();

// Invocation expressions already omit the CS1612 error when the setter is readonly:
c.ArraySegmentMethod()[10] = new object();

// In limited cases, ref-returning indexers can be used to work around this:
c.RefReturningIndexerWorkaround[10] = new object();

_ = new C
{
// Remove the current CS1918 error:
ArraySegmentProp = { [10] = new object() },
// Remove the current CS1918 error:
RefReturningIndexerWorkaround = { [10] = new object() },
};

class C
{
public ArraySegment ArraySegmentProp { get; set; }
public ArraySegment ArraySegmentMethod() => ArraySegmentProp;

public Span RefReturningIndexerWorkaround => ArraySegmentProp.AsSpan();
}

// Partial declaration of System.ArraySegment for demonstration
public readonly struct ArraySegment
{
// Implicitly readonly due to the readonly modifier on the struct
public T this[int index] { get => ...; set => ...; }
}
```

Currently, the code above gives the error CS1612 "Cannot modify the return value of 'C.ArraySegmentProp' because it is not a variable." This restriction is unnecessary when the setter is readonly. The restriction is there to remind you to assign the modified struct value back to the property. But there is no supported modification to the struct value when the setter is readonly, so there is no reason to assign back to the property.

```cs
// Requested by the current CS1612 error:
var temp = c.ArraySegmentProp;
temp[10] = new object();
c.ArraySegmentProp = temp; // But this line is purposeless; 'temp' cannot have changed.
```

## Design meetings

* https://github.com/dotnet/csharplang/blob/main/meetings/2025/LDM-2025-03-19.md#readonly-setters-on-non-variables
* https://github.com/dotnet/csharplang/blob/main/meetings/2025/LDM-2025-04-02.md#readonly-setters

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.