Skip to main content

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:

  1. It only has a get; accessor.
  2. It uses the expression-bodied syntax => (which implies a getter-only).
  3. It has a private set;, and you are trying to set it from outside the class.
  4. 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.

  1. Check for set: If it's missing, add { get; set; }.
  2. Check for =>: Expression bodies are read-only.
  3. Check for init: These can only be set in the Object Initializer { ... }.
  4. Check Visibility: If the setter is private, use a constructor or a public method to change the value.