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:
- Grandparent: Defines
virtual. - Parent: Overrides it, and marks it
sealed. - 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() { }
}
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.
- Check Keywords: Do you have
sealedwithoutoverride? - 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
sealedonly if you want to stop future subclasses from overriding it.
- If defining a new method: Remove