Skip to main content

How to Resolve Error "CS0238: 'member' cannot be sealed because it is not an override" in C#

The Compiler Error CS0238 is a syntax and logic error regarding inheritance modifiers. The message reads: " 'MemberName' cannot be sealed because it is not an override".

In C#, the sealed keyword on a method or property has a specific purpose: to stop further overriding in derived classes. Logic dictates that you can only "stop" overriding if you are currently "doing" an override. Therefore, sealed can only be applied to a member that is also marked with override.

You cannot seal a virtual method (because virtual means "open for extension") and you cannot seal a standard method (because standard methods are already effectively sealed).

Understanding the Purpose of Sealed Methods

In C#, methods are sealed (final) by default. If you define a method void DoWork(), no child class can override it.

  • virtual: "I am opening this method up for modification by children."
  • override: "I am a child, and I am modifying the parent's method."
  • sealed override: "I am modifying the parent's method, BUT I am locking it so my children cannot modify it further."

The error CS0238 occurs because you tried to use sealed without override, which creates a logical contradiction or redundancy.

Scenario 1: Sealing a New or Virtual Method

A common mistake is trying to declare a method as virtual (overridable) but also sealed (not overridable) at the same time.

Example of error

public class BaseClass
{
// ⛔️ Error CS0238: 'DoSomething' cannot be sealed because it is not an override.
// Contradiction: 'virtual' says "Please override me",
// 'sealed' says "Don't override me".
public sealed virtual void DoSomething()
{
}
}

Solution

If you want the method to be overridable, remove sealed. If you don't want it to be overridable, remove virtual (and sealed).

public class BaseClass
{
// ✅ Correct: Open for overriding
public virtual void DoSomething()
{
}
}

Scenario 2: Sealing a Non-Virtual Method

Sometimes developers explicitly add sealed to a standard method to emphasize that it shouldn't be overridden. However, C# methods are non-virtual by default, so this is invalid syntax.

Example of error

public class Utility
{
// ⛔️ Error CS0238: 'Calculate' cannot be sealed because it is not an override.
// Standard methods are ALREADY sealed implicitly.
public sealed void Calculate()
{
}
}

Solution

Simply remove the keyword.

public class Utility
{
// ✅ Correct: Implicitly sealed. Derived classes cannot override this.
public void Calculate()
{
}
}

Solution: Correct Usage in Inheritance Chains

The sealed keyword on methods is only valid when you are in a Derived Class and you want to put an end to the polymorphism chain started by a base class.

The Correct Pattern:

  1. Grandparent: Defines virtual.
  2. Parent: Overrides it, and marks it sealed.
  3. Child: Cannot override it.
// 1. The Base Class starts the chain
public class GrandParent
{
public virtual void Speak() => Console.WriteLine("Grandparent speaks");
}

// 2. The Derived class modifies and LOCKS the chain
public class Parent : GrandParent
{
// ✅ Correct: 'sealed' modifies 'override'.
// This implies: "I am overriding GrandParent, but I forbid my children from overriding me."
public sealed override void Speak() => Console.WriteLine("Parent speaks");
}

// 3. The Final class
public class Child : Parent
{
// ⛔️ Compiler Error (CS0239): Cannot override because 'Parent.Speak' is sealed.
// public override void Speak() { }
}
note

Sealed Classes: You can mark an entire class as sealed (public sealed class MyClass). This prevents inheritance entirely. This is different from marking individual methods as sealed.

Conclusion

CS0238 is a logic check ensuring you don't lock a door that isn't open.

  1. Check Keywords: Do you have sealed without override?
  2. Fix Definition:
    • If defining a new method: Remove sealed. (It is sealed by default).
    • If defining a virtual method: Remove sealed. (You cannot start a virtual chain and stop it in the same line).
    • If overriding a method: Keep sealed only if you want to stop future subclasses from overriding it.