Skip to content

How to Resolve Error "CS0200: Property or indexer cannot be assigned to" in C#

Fix the CS0200 compiler error in C# by understanding read-only properties, missing setters, expression-bodied properties, init-only accessors, and private setters.

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.
Navigation