How to Resolve Error "CS0502: 'member' cannot be both abstract and sealed" in C#
The Compiler Error CS0502 is a logical contradiction error. The message reads: "'member' cannot be both abstract and sealed".
In C#, the keywords abstract and sealed represent opposite concepts regarding inheritance:
abstract: "This member has no implementation. Derived classes MUST override it."sealed: "This member is complete. Derived classes CANNOT override it."
Combining these two creates a paradox: you are asking for a method that must be overridden but simultaneously forbids overriding. The compiler rejects this impossible instruction.
Understanding the Contradiction
To define a member, you must choose its inheritance behavior:
- Abstract: No body provided. Implementation required by children.
- Virtual: Body provided. Overriding allowed by children.
- Sealed (on Override): Body provided. Further overriding prevented.
- Standard (Non-virtual): Body provided. Overriding impossible.
abstract sealed attempts to define a member with no body (because it is abstract) that cannot be implemented (because it is sealed). This renders the member permanently unusable.
Scenario: The Invalid Combination
This error often occurs when a developer wants to define a strict contract but misunderstands the terminology, confusing "sealed" (final) with "static" or simply piling on keywords.
Example of error:
public abstract class GameEntity
{
// ⛔️ Error CS0502: 'Update' cannot be both abstract and sealed.
// Abstract says: "Child classes, please write the code for this."
// Sealed says: "Child classes, do not touch this."
public abstract sealed void Update();
}
Solution 1: Make it Abstract (Allow Inheritance)
If your intention is to force derived classes to provide the logic, use abstract. This requires the containing class to be abstract as well.
Solution: remove the sealed keyword.
public abstract class GameEntity
{
// ✅ Correct: Defines a contract.
// Derived classes MUST implement Update().
public abstract void Update();
}
public class Player : GameEntity
{
public override void Update()
{
// Implementation provided here
}
}
Solution 2: Make it Standard (Prevent Inheritance)
If your intention is to provide a method that strictly cannot be changed or overridden by derived classes, you do not use abstract.
- If it is a new method in a base class: Just write a standard method (do not mark it
virtual). Standard methods are sealed by default. - If you are overriding a parent method and want to stop further changes: Use
sealed override.
Solution: New Member
Remove abstract and sealed. Provide a body.
public class GameEntity
{
// ✅ Correct: A standard method.
// It has a body, and child classes cannot override it
// (because it is not marked virtual).
public void Update()
{
System.Console.WriteLine("Updating Entity...");
}
}
Solution: Stopping Inheritance
If you are overriding a base member but want to stop the chain there:
public class Parent
{
public virtual void Move() { }
}
public class Child : Parent
{
// ✅ Correct: We provide implementation (override)
// but stop future subclasses from changing it (sealed).
// Note: It CANNOT be abstract.
public sealed override void Move()
{
/* Final logic */
}
}
Conclusion
CS0502 prevents you from creating a dead-end method definition.
- Choose a Path: Do you want children to implement the logic (
abstract)? Or do you want to lock the logic down (sealed/ standard)? - Remove Keywords: You can never use
abstractandsealedtogether. Pick the one that matches your design intent.