Back to Blog
C#

C# Sealed Method: Preventing Overrides

c# sealed method: Learn how to declare a sealed method in C#, what it prevents, and when to use it to control inheritance behavior.

C#sealedinheritanceoverridevirtualOOP
Diagram showing a sealed method preventing a derived class from overriding it

c# sealed method requires a clear understanding of the core syntax, runtime behavior, and practical implementation patterns demonstrated in the examples below.

When you mark a method as sealed in C#, you are telling the compiler that no further derived class may override that method. The sealed modifier is only valid on an override method, and it stops the virtual dispatch chain from extending further down the hierarchy. This article explains the exact syntax, the rules that govern sealed methods, and the design and runtime implications of using them.

What a Sealed Method Actually Prevents

In C#, a method can be overridden only if it is declared virtual, abstract, or override in a base class. When a derived class overrides such a method, it can choose to seal that override. Once sealed, any class derived from that class cannot override the method again. The method remains virtual for the classes below the sealing class, but the sealing class's override becomes the final implementation in that branch of the hierarchy.

Consider this example:

public class BaseService { public virtual void Execute() { Console.WriteLine("Base implementation"); } } public class DerivedService : BaseService { public sealed override void Execute() { Console.WriteLine("Derived implementation"); } } public class MoreDerivedService : DerivedService { // This will not compile: // public override void Execute() { } }

The sealed keyword on DerivedService.Execute prevents MoreDerivedService from overriding it. Without sealed, MoreDerivedService could provide its own implementation, and the virtual call chain would continue.

Requirements for Declaring a Sealed Method

The sealed modifier can only be applied to a method that is already an override. You cannot seal a method that is not overriding something. For example, you cannot write:

public class MyClass { public sealed void DoWork() { } // Compiler error CS0238 }

The compiler error CS0238 states that sealed cannot be used because the method is not an override. To seal a method, the method must be declared with override and the base method must be virtual, abstract, or override. The sealed modifier is placed before override in the method declaration.

A sealed method can also be declared in a class that is itself not sealed. Sealing a method is independent of sealing the entire class. You can seal a single method while leaving other virtual methods open for further override.

Sealed Methods in Inheritance Hierarchies

The effect of sealed is visible when you have a chain of inheritance. The method is virtual for the class that first declares it, and each override can either keep it virtual or seal it. Once sealed, the method is no longer virtual for any class below that point. This means that a call to the method on a MoreDerivedService instance will always dispatch to the sealed implementation, even if the variable is typed as the base class.

The following code demonstrates the runtime behavior:

BaseService service = new MoreDerivedService(); service.Execute(); // Calls DerivedService.Execute

Because DerivedService sealed the override, the runtime does not need to look further down the hierarchy for another override. The method resolution is fixed at the sealed level.

Why You Would Seal a Method

Sealing a method is a design decision. It communicates that the implementation in the derived class is final and should not be changed by further subclasses. This is useful when:

  • The derived class provides a specific behavior that must remain consistent across all subclasses.
  • The method relies on internal state or invariants that a subclass could break by overriding.
  • You want to prevent accidental or intentional modification of critical logic.

For example, a base class might define a template method that calls several steps. A derived class overrides the template method and seals it to ensure that the orchestration logic cannot be altered, while still allowing subclasses to override individual steps if they remain virtual.

Sealing a method also has a maintainability benefit: it reduces the surface area of overridable methods, making the class hierarchy easier to reason about. Developers reading the code know that the sealed method's behavior is fixed.

Performance and Runtime Considerations

The sealed modifier can have a positive effect on performance, though the details depend on the runtime and the JIT compiler. In .NET, virtual method calls require an indirect lookup through the vtable. A sealed method, because it cannot be overridden further, can sometimes be called directly if the compiler can prove the exact type. The JIT may devirtualize such calls, turning an indirect call into a direct call, which is faster.

However, this is an optimization that the JIT may or may not apply. It is not guaranteed by the C# language specification. The performance benefit, when it occurs, comes from avoiding the vtable indirection. For most applications, the difference is negligible, but in hot paths with many polymorphic calls, sealing methods that are not intended to be overridden can help the JIT produce more efficient code.

It is important to note that sealing a method does not change the behavior of the method itself; it only changes the set of overrides that can exist. The actual implementation is identical whether the method is sealed or not.

Sealed Methods vs Sealed Classes

A sealed class prevents any class from deriving from it, which means all its methods are effectively non-overridable for external classes. Sealing a single method is more granular. You can allow further inheritance but stop the override of one specific method. Choose between them based on the level of control you need.

ModifierScopeEffect
sealed methodSingle methodPrevents further override of that method
sealed classEntire classPrevents all inheritance from that class

A sealed class is a stronger constraint. It is appropriate when the class is designed to be a leaf in the hierarchy. A sealed method is appropriate when you want to allow subclassing but want to lock down a particular behavior.

Common Mistakes and Edge Cases

One common mistake is trying to seal a method that is not an override. The compiler will reject this with CS0238. Another mistake is sealing a method in a class that is later used as a base for a class that tries to override it; that override will fail to compile.

There is also a subtle interaction with new methods. If a derived class declares a method with the same signature using new (hiding the base method), that new method is not an override, and it cannot be sealed. Sealing only applies to the override chain.

Another edge case: a sealed method can still be called from a derived class, but the derived class cannot change its implementation. If a subclass needs to alter behavior, it must call the sealed method and add logic around it, or the design should be reconsidered.

When Not to Seal a Method

Sealing a method reduces extensibility. If you are building a framework or library where consumers are expected to customize behavior by subclassing, sealing too many methods can make the API rigid. It can also interfere with testing frameworks that rely on overriding methods to mock behavior. Many mocking libraries use dynamic proxy generation and require methods to be virtual and overridable. Sealing a method can make a class difficult to mock, forcing you to use interfaces or other techniques.

Consider the tradeoff: sealing a method gives you control but takes away flexibility. Only seal when you are confident that no legitimate subclass should ever need to change the implementation.

c# sealed method: Practical Usage and Code Examples | RYUSLOG DEV