Skip to main content

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:

  1. Abstract: No body provided. Implementation required by children.
  2. Virtual: Body provided. Overriding allowed by children.
  3. Sealed (on Override): Body provided. Further overriding prevented.
  4. 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.

  1. Choose a Path: Do you want children to implement the logic (abstract)? Or do you want to lock the logic down (sealed / standard)?
  2. Remove Keywords: You can never use abstract and sealed together. Pick the one that matches your design intent.