Sealed Classes in C#

Jiyan Epözdemir
C# Programming
Published in
7 min readApr 11, 2024

Let’s say, you’ve designed a class that represents a key component of your application. Now, you want to make sure that no one can come along and mess with its inner workings. That is the main purpose of sealed classes. They act as the gatekeepers, ensuring that your classes remain same and impervious to unwanted changes.

Sealed classes are like the “do not disturb” signs in the object-oriented programming. They mark certain classes as off-limits for inheritance, ensuring their integrity and stability. They lock down certain classes, preventing them from being inherited or modified beyond their initial design.

In this blog post, We’ll go over how to use and create a sealed C# class. We will also look at the rationale behind developers’ use of sealed classes in code and libraries.

What is a Sealed Class?

In C#, a sealed class is one that cannot be inherited. It’s like a closed book — once written, its content cannot be extended or modified. Think of it as a finished product, ready to be used without any alterations.

Why Seal a Class?

The idea behind sealing a class is to prevent further inheritance. But why would you want to do that? Well, there are a few reasons:

  1. Security: By sealing a class, you’re restricting access to its internals, which can enhance security by preventing unintended modifications or extensions.
  2. Performance: Sealed classes can sometimes offer performance benefits because the compiler can make certain optimizations knowing that the class won’t be subclassed.
  3. Design Intent: It also communicates your design intent clearly — if a class is sealed, it signals to other developers that you don’t intend for it to be subclassed.

How to Define a Sealed Class?

Creating a sealed class in C# is quite simple. Here’s a quick example:

sealed class MySealedClass
{
// Class members and methods go here
}

That’s it! By adding the sealed keyword before the class keyword, you've effectively sealed off this class from any further inheritance.

If a class tries to inherit from a sealed class, an error will be produced saying “Cannot inherit from a sealed class”.

Let’s try a different real-world example to illustrate the restrictions of a sealed class in a simpler way.

Imagine you’re designing a game and you need to create a class to represent a player’s character. Let’s call it PlayerCharacter. Now, you want to ensure that no one can create a subclass of PlayerCharacter, because you want to maintain a consistent behavior for all player characters throughout the game.

public sealed class PlayerCharacter
{
public string Name { get; }
public int Level { get; }
public int Health { get; private set; }

public PlayerCharacter(string name, int level, int health)
{
Name = name;
Level = level;
Health = health;
}

public void TakeDamage(int damage)
{
Health -= damage;
// Additional logic for handling damage...
}
}

In this example, the PlayerCharacter class is sealed, meaning it cannot be inherited by any other class. This ensures that no subclasses like Warrior or Mage can be created, restricting the game to have only one type of player character.

By sealing the PlayerCharacter class, you maintain a consistent behavior for all player characters in the game. Each player character will have the same properties and methods, ensuring a balanced gaming experience.

Sealing the class simplifies the application design. You don’t have to worry about different subclasses introducing complex interactions or unexpected behaviors. It also prevents other developers from unintentionally creating subclasses that could potentially break the application logic or introduce security vulnerabilities.

Now, let’s see how attempting to inherit from a sealed class produces a compilation error in C#. We’ll use the same example of a sealed PlayerCharacter class.

// Trying to inherit from a sealed class
public class Warrior : PlayerCharacter
{
// Warrior-specific properties and methods...
}

We’re attempting to create a subclass Warrior that inherits from the sealed class PlayerCharacter. However, when you try to compile this code, you'll encounter a compilation error:

error CS0509: 'Warrior': cannot derive from sealed type 'PlayerCharacter'

This error message indicates that you cannot derive a class from a sealed type, such as PlayerCharacter. The compiler prevents this because the PlayerCharacter class is explicitly marked as sealed, meaning it cannot be inherited.

This restriction ensures that the PlayerCharacter class remains sealed and cannot be extended, maintaining consistency and preventing unintended modifications in the codebase.

Sealed Methods

You can mark individual methods as sealed, just like you can mark entire classes as sealed. When you seal a method, you prevent it from being overridden by subclasses. This means that the sealed method’s implementation cannot be changed or extended in any subclass.

Let’s use the same example of a player character in a game to demonstrate sealed methods.

using System;

public class PlayerCharacter
{
public virtual string Name { get; set; }
public virtual int Level { get; set; }
public virtual int Health { get; set; }

public virtual void Attack()
{
Console.WriteLine("Player character attacks!");
}
}

public class Warrior : PlayerCharacter
{
public sealed override void Attack()
{
Console.WriteLine("Warrior character attacks with sword!");
}

public virtual void Block()
{
Console.WriteLine("Warrior character blocks with shield!");
}
}

public class Knight : Warrior
{
// Attempting to override the sealed Attack method will produce a compilation error
// public override void Attack() { }

// Attempting to override the Block method is allowed
public override void Block()
{
Console.WriteLine("Knight character blocks with heavy armor!");
}
}

class Program
{
static void Main(string[] args)
{
PlayerCharacter player1 = new Warrior();
player1.Attack(); // Output: Warrior character attacks with sword!

PlayerCharacter player2 = new Knight();
player2.Block(); // Output: Knight character blocks with heavy armor!
}
}
  • The PlayerCharacter class has a virtual method Attack, which represents a basic attack action for any player character.
  • The Warrior class inherits from PlayerCharacter and overrides the Attack method with a specific attack action for warriors, sealing it to prevent further overriding in subclasses.
  • The Knight class further subclasses Warrior and provides its own implementation of the Block method, demonstrating that non-sealed methods can still be overridden in subclasses.

Note that, attempting to override the sealed Attack method in the Knight class would result in a compilation error, as indicated in the commented-out code.

error CS0239: 'Knight.Attack()': cannot override inherited member 'Warrior.Attack()' because it is sealed

This compilation error occurs because the Attack method in the Warrior class is sealed, preventing it from being overridden in the Knight class. Therefore, attempting to override the sealed Attack method in the Knight class (public override void Attack() { }) results in the compiler error CS0239.

Sealed Properties

Similar to methods, you can also seal individual properties in C#. Sealing a property prevents it from being overridden in derived classes. This can be useful when you want to ensure that a property’s behavior remains consistent across all subclasses.

Let’s incorporate property sealing into the example of player characters:

using System;

public class PlayerCharacter
{
public virtual string Name { get; set; }
public virtual int Level { get; set; }
public virtual int Health { get; set; }
}

public class Warrior : PlayerCharacter
{
public sealed override string Name
{
get { return "Warrior"; }
set { Console.WriteLine("Name cannot be changed for Warrior."); }
}
}

public class Knight : Warrior
{
// Attempting to override the sealed property will produce a compilation error
// public override string Name { get; set; }
}
  • The Warrior class inherits from PlayerCharacter and seals the Name property, providing a specific implementation that always returns "Warrior" and prevents its value from being changed.
  • The Knight class further subclasses Warrior and attempts to override the Name property, resulting in a compilation error due to the property being sealed.

The compilation error message would indicate that attempting to override the sealed Name property in the Knight class is not allowed.

error CS0239: 'Knight.Name': cannot override inherited member 'Warrior.Name' because it is sealed

When to Use Sealed Classes?

Now, you might be wondering, “When should I actually use sealed classes?” Well, it depends on your specific scenario. Here are a few situations where sealing a class might be beneficial:

  • Utility Classes: If you have a class that contains only static methods or fields and doesn’t require inheritance, sealing it can prevent accidental subclassing.
  • Immutable Classes: Classes that represent immutable data (data that cannot be changed once created) can often benefit from being sealed to maintain their immutability.
  • Framework Design: When designing APIs or frameworks, sealing certain classes can help maintain control over how they’re used and extended.

Conclusion

And there you have it — a beginner’s guide to sealed classes in C#! We’ve covered what they are, why you might want to use them, how to define them, and when they might come in handy. Sealed classes might seem like a small detail, but they can play a significant role in crafting robust, secure, and maintainable code. These special classes offer a level of control and predictability that can greatly enhance the reliability of your code. Imagine building a house with sealed doors — once everything is in place, you lock them down to keep everything secure. Sealed classes work in a similar way, providing a barrier against unexpected modifications.

So, next time you’re designing a class in C#, consider whether sealing it might be the right choice.

Thank you for reading!

If you found this post helpful, don’t forget to give it a clap and share it with others who might benefit from it.👏👏👏👏👏

--

--

Jiyan Epözdemir
C# Programming

I am a multi-disciplined Software Architect and Computer Engineer, MSc. I enjoy building awesome softwares & applications.