Skip to main content

How to Resolve Error "CS0546: 'Child.Property.set': cannot override because 'Parent.Property' does not have an overridable set accessor" in C#

The Compiler Error CS0546 is an inheritance constraint error. The message reads: "'Child.Property.set': cannot override because 'Parent.Property' does not have an overridable set accessor".

In C#, when you override a property, you are overriding its individual accessors (get and set). This error occurs when you attempt to override the set accessor in a derived class, but the base class property either does not have a setter (it is Read-Only), or the setter exists but is not virtual (or private/internal and inaccessible).

This guide explains how property overriding mechanics work and how to resolve this accessor mismatch.

Understanding Property Accessor Overriding

You cannot add capabilities to a virtual member via an override. You can only replace existing capabilities.

  • If the Base Class says: "I have a virtual get."
  • The Child Class cannot say: "I override your get, AND I override your set."

Since the base class never established a "virtual slot" for the setter, there is nothing for the child class to override.

Scenario 1: Overriding a Read-Only Property

This is the most common cause. The base class defines a property meant to be computed or read-only, but the child class tries to make it writable using override.

Example of error

public class BaseClass
{
// Virtual Read-Only Property
public virtual int Value
{
get { return 10; }
}
}

public class DerivedClass : BaseClass
{
// ⛔️ Error CS0546: 'DerivedClass.Value.set': cannot override because
// 'BaseClass.Value' does not have an overridable set accessor.
public override int Value
{
get { return 20; }
set { } // Trying to add a setter where none existed
}
}

Solution: Remove the Setter

If you must use override, you are restricted to the shape of the parent property.

public class DerivedClass : BaseClass
{
// ✅ Correct: Only overriding the getter matches the base class contract.
public override int Value
{
get { return 20; }
}
}

Scenario 2: Private or Non-Virtual Setters

Sometimes the base class does have a setter, but it is not available for overriding because it is private or simply not marked virtual (if virtual modifiers are split).

Example of error :

public class BaseAccount
{
// The property is virtual, but the setter is implicitly private by logic or omission
// (though standard syntax usually makes both virtual).
// A clearer example involves split definitions or compilation boundaries.

public virtual int ID { get; private set; }
}

public class MyAccount : BaseAccount
{
// ⛔️ Error CS0546: The base 'set' is private. You cannot override it.
public override int ID
{
get { return base.ID; }
set { base.ID = value; } // Invalid access
}
}

Solution 1: Remove the Setter from the Override

If you do not need to change the setting logic, simply omit the set block in your override. The base class's setter remains active (if accessible) or hidden.

public class MyAccount : BaseAccount
{
// ✅ Correct: We override the 'get', but leave 'set' alone.
public override int ID
{
get { return 100; }
}
}

Solution 2: Use new to Shadow the Property

If you fundamentally need to change the property from Read-Only to Read-Write in the derived class, you are no longer doing polymorphism. You are defining a new API. Use the new keyword.

Solution:

public class BaseClass
{
public virtual int Value { get { return 10; } }
}

public class DerivedClass : BaseClass
{
private int _val;

// ✅ Correct: 'new' hides the base property.
// This allows us to define a completely new structure with a setter.
public new int Value
{
get { return _val; }
set { _val = value; }
}
}
warning

Shadowing Behavior: BaseClass b = new DerivedClass(); will invoke the Base (Read-Only) property. DerivedClass d = new DerivedClass(); will invoke the Derived (Read-Write) property.

Conclusion

CS0546 ensures you respect the read/write contract of the base class.

  1. Check the Base: Does the parent property have a set accessor?
  2. Check Visibility: Is the setter private? If so, you cannot override it.
  3. Align: Remove the set from your override, or use new to create a totally different property.