In this article, we will learn about the sealed class and the sealed keyword in C#. In short, we can not inherit a sealed class with any other class. We can not use a sealed class as a base class. In case you want to enforce certain behaviours and prevent further modifications through inheritance then a sealed keyword is useful.
Please read this blog: static vs readonly keyword in C#
Features of Sealed Class in C#
- Prevent Inheritance: The primary feature of a sealed class is that we cannot inherit this class. This ensures that the class’s implementation remains unchanged.
- Optimization: Sealed classes can sometimes provide performance benefits because the compiler knows that there will be no derived classes, which can simplify certain optimizations.
- Security: By sealing a class, we can prevent potential security risks to avoid potential misuse.
Syntax
In C#, you use the sealed
keyword to define a sealed class. Here is a basic syntax to use sealed keyword in C#:
public sealed class MySealedClass
{
// Class members go here
}
Example of a Sealed Class
Consider a scenario where you have a class BankAccount
that you do not want to be inherited to ensure that its core functionality remains intact. Here’s how you can define and use a sealed class:
using System;
namespace SealedClassExample
{
// Define a sealed class
public sealed class BankAccount
{
private double balance;
public BankAccount(double initialBalance)
{
balance = initialBalance;
}
public void Deposit(double amount)
{
if (amount > 0)
{
balance += amount;
Console.WriteLine($"Deposited: {amount}, New Balance: {balance}");
}
}
public void Withdraw(double amount)
{
if (amount > 0 && amount <= balance)
{
balance -= amount;
Console.WriteLine($"Withdrew: {amount}, New Balance: {balance}");
}
else
{
Console.WriteLine("Insufficient funds or invalid amount.");
}
}
public double GetBalance()
{
return balance;
}
}
// Trying to inherit from BankAccount will cause a compile-time error
// public class SavingsAccount : BankAccount
// {
// }
class Program
{
static void Main(string[] args)
{
BankAccount account = new BankAccount(1000);
account.Deposit(500);
account.Withdraw(200);
Console.WriteLine($"Final Balance: {account.GetBalance()}");
}
}
}
Code Explanation
- Sealed Class Declaration: The
BankAccount
class is declared as sealed using thesealed
keyword. - Class Members: It contains the private member
balance
, and methodsDeposit
,Withdraw
, andGetBalance
to manage the account balance. - Usage: In the
Main
method, an instance ofBankAccount
is created, and various operations are performed on it. - Inheritance Prevention: Any attempt to inherit from
BankAccount
(as shown in the commented-outSavingsAccount
class) will result in a compile-time error.
When to avoid Sealed Class in our project
While sealed classes in C# can be beneficial for preventing inheritance and maintaining the integrity of your code, there are scenarios where you should avoid using them.
- Sealed classes can make unit testing more challenging. In testing, it is common to use mocking frameworks to create mock objects of classes. If we declare a class as Sealed, then we can not inherit it and this way it might be a restriction in unit cases.
- Sealed classes cannot participate in polymorphic behaviours, which is a fundamental concept in object-oriented programming.
- When designing components that are part of a larger system, sealing classes can reduce the component’s ability to interact flexibly with other parts of the system.
Let’s see the limitations of sealed class with the help of an example
public class Vehicle
{
public virtual void Drive()
{
Console.WriteLine("Vehicle is driving");
}
}
public class Car : Vehicle
{
public override void Drive()
{
Console.WriteLine("Car is driving");
}
}
public class Truck : Vehicle
{
public override void Drive()
{
Console.WriteLine("Truck is driving");
}
}
In this example, if the Vehicle
class were sealed, it would prevent the creation of Car
and Truck
classes, thereby limiting the extensibility of the code.