How to Resolve Error "CS0200: Property or indexer 'property' cannot be assigned to" in C#
The Compiler Error CS0200 is an assignment restriction error. The message reads: "Property or indexer 'Name' cannot be assigned to -- it is read only".
In C#, properties define how data is accessed (get) and modified (set). If a property lacks a set accessor (or an init accessor used in the correct context), it is considered Read-Only. The compiler prevents you from using the assignment operator = on these properties because the class does not define a way to accept the new value.
This guide explains how to identify read-only properties and the different ways to enable assignment or correctly initialize them.
Understanding Read-Only Properties
A property becomes read-only in the following situations:
- It only has a
get;accessor. - It uses the expression-bodied syntax
=>(which implies a getter-only). - It has a
private set;, and you are trying to set it from outside the class. - It has an
init;accessor, and you are trying to set it after the initialization phase.
To fix CS0200, you must either add a setter, change where you assign the value (move it to the constructor), or fix the visibility modifiers.
Scenario 1: Missing Set Accessor
This is the most common cause. You declared a property to hold data, but you forgot to include the set keyword.
Example of error
public class User
{
// ⛔️ Error: This property has no setter. It is immutable.
public string Username { get; }
}
public class Program
{
static void Main()
{
var u = new User();
// ⛔️ Error CS0200: Property 'Username' cannot be assigned to
u.Username = "Alice";
}
}
Solution: Add set
If the property is intended to be mutable (changeable at any time), add set.
public class User
{
// ✅ Correct: Added 'set'
public string Username { get; set; }
}
Scenario 2: Expression-Bodied Properties (=>)
Properties defined using the lambda arrow => are Getter-Only by definition. They calculate a value every time they are accessed. You cannot assign a value to them because they are calculations, not storage fields.
Example of error
public class Rectangle
{
public int Width { get; set; }
// This is a calculated property (Getter only)
public int Area => Width * Width;
}
public class Program
{
static void Main()
{
var r = new Rectangle();
// ⛔️ Error CS0200: You cannot assign to 'Area'.
// It is a formula, not a variable.
r.Area = 50;
}
}
Solution: Change Logic or Syntax
If you want to store the area manually, convert it to a standard property.
public class Rectangle
{
public int Width { get; set; }
// ✅ Correct: Converted to auto-property
public int Area { get; set; }
}
Scenario 3: The init Accessor Restriction
Introduced in C# 9.0, the init accessor creates Immutable properties that can only be set during object creation. Once the construction phase is over, they become read-only.
Example of error
public class Config
{
public string Environment { get; init; }
}
public class Program
{
static void Main()
{
// Initialization phase - Valid
var c = new Config { Environment = "Production" };
// ⛔️ Error CS0200: Cannot assign to 'Environment'
// because it is an 'init-only' property.
c.Environment = "Development";
}
}
Solution: Use Object Initializers
You must assign the value when you first create the object. If you need to change it later, init is the wrong tool; switch to set.
// ✅ Correct: Set during creation
var c = new Config { Environment = "Production" };
Scenario 4: Private Setters
Sometimes a property has a setter, but it is marked private or protected. To the outside world (like the Main method), that property appears read-only.
Example of error
public class Account
{
public decimal Balance { get; private set; }
}
public class Program
{
static void Main()
{
var acc = new Account();
// ⛔️ Error CS0200 (or CS0272): The setter is inaccessible.
acc.Balance = 1000;
}
}
Solution: Use Constructor or Methods
If the setter is private for safety reasons (Encapsulation), you should provide a public method or a constructor to modify the state safely.
public class Account
{
public decimal Balance { get; private set; }
public Account(decimal initialBalance)
{
// ✅ Correct: Private setters are accessible inside the class/constructor
Balance = initialBalance;
}
public void Deposit(decimal amount)
{
Balance += amount;
}
}
Conclusion
CS0200 ensures that you don't try to write data to a place that can't accept it.
- Check for
set: If it's missing, add{ get; set; }. - Check for
=>: Expression bodies are read-only. - Check for
init: These can only be set in the Object Initializer{ ... }. - Check Visibility: If the setter is
private, use a constructor or a public method to change the value.