;

C# Sealed Class and Methods


In C#, the concept of sealed classes and sealed methods is used to restrict inheritance and prevent further modification of certain class members. The sealed keyword is applied to classes and methods to stop them from being extended or overridden. This helps when you want to make a class or method final to avoid potential issues caused by overriding in derived classes.

In this tutorial, we will explore what sealed classes and methods are, how they are used, when to apply them, and their impact on code design. We will also provide examples and explain their real-world applications.

What is a Sealed Class?

A sealed class in C# is a class that cannot be inherited by any other class. By marking a class as sealed using the sealed keyword, you essentially lock the class and prevent anyone from deriving new classes from it.

This is useful when you are confident that no other class should alter the behavior of the sealed class, or when you want to optimize performance by removing the overhead of the runtime checking for inheritance.

Characteristics of a Sealed Class:

  • The sealed keyword is used to prevent inheritance.
  • Once a class is marked as sealed, no other class can extend it.
  • Sealed classes are often used when the class has been fully implemented, and no further modifications are needed.
public sealed class Car
{
    public void Drive()
    {
        Console.WriteLine("The car is being driven.");
    }
}

// This would cause a compile-time error
// public class SportsCar : Car { }

In the above example, the Car class is sealed, which means no class can inherit from it, and trying to do so would result in a compilation error.

What is a Sealed Method?

A sealed method is a method that prevents overriding in derived classes. It is used in conjunction with the override keyword. A method can only be sealed if it is overriding a base class method. You cannot apply the sealed keyword to a method unless it is first an overridden method.

Characteristics of a Sealed Method:

  • A sealed method prevents further overriding by any derived class.
  • It is only applicable to methods that are already marked as override.
  • It provides a way to stop the virtual inheritance chain for specific methods.
public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Animal sound");
    }
}

public class Dog : Animal
{
    public sealed override void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}

// Attempting to override MakeSound in a further derived class will result in an error:
// public class Bulldog : Dog
// {
//     public override void MakeSound() // Error: Cannot override sealed method
//     {
//         Console.WriteLine("Bulldog barking");
//     }
// }

Here, the Dog class overrides the MakeSound method from the Animal class and marks it as sealed. This prevents any further derived classes (like Bulldog) from overriding the method.

Use Cases for Sealed Classes and Methods

Sealed Classes:

  1. Security and Integrity: If your class performs sensitive operations or is critical to the application's core functionality, you may want to seal it to prevent others from altering its behavior via inheritance.
  2. Performance Optimization: The runtime doesn't need to check for inheritance if a class is sealed, which can result in minor performance improvements.
  3. Final Implementation: If the class represents a final, fully implemented entity (e.g., System.String is sealed), then you may seal it to lock its behavior.

Sealed Methods:

  1. Restricting Further Overrides: Sometimes you override a method in a subclass, and you're confident no further changes should be made. Sealing the method can enforce this.
  2. Preventing Inconsistent Behavior: Sealing methods that are core to the functionality of the class can prevent future developers from overriding them in a way that might break the expected behavior.

Examples of Sealed Classes and Methods

Basic Example of Sealed Class

public sealed class DatabaseConnection
{
    public void OpenConnection()
    {
        Console.WriteLine("Database connection opened.");
    }

    public void CloseConnection()
    {
        Console.WriteLine("Database connection closed.");
    }
}

// This would cause an error because the class is sealed
// public class MySQLConnection : DatabaseConnection { }

Here, the DatabaseConnection class is sealed, which means no one can extend it. This ensures that the connection logic is not altered by subclassing, which might introduce bugs or security vulnerabilities.

Real-World Example of Sealed Method

Let's consider a payment system where a base PaymentProcessor class allows different types of payment processing. We will demonstrate sealing a method to prevent further overriding in subclasses.

public class PaymentProcessor
{
    public virtual void ProcessPayment(double amount)
    {
        Console.WriteLine($"Processing payment of {amount}");
    }
}

public class CreditCardProcessor : PaymentProcessor
{
    // Sealed method, cannot be overridden by any further derived classes
    public sealed override void ProcessPayment(double amount)
    {
        Console.WriteLine($"Processing credit card payment of {amount}");
    }
}

// Attempting to override the sealed method in a derived class would result in an error:
// public class CustomCreditCardProcessor : CreditCardProcessor
// {
//     public override void ProcessPayment(double amount) // Error: Cannot override sealed method
//     {
//         Console.WriteLine($"Custom processing of credit card payment of {amount}");
//     }
// }

In this case:

  • PaymentProcessor is the base class with a ProcessPayment method that can be overridden.
  • CreditCardProcessor overrides the method and marks it as sealed, preventing any other class from further overriding this method.

Real-World Application:

In financial applications, preventing further modification of key operations like payment processing ensures that your critical business logic remains consistent and secure. By sealing the method, you prevent future developers from accidentally altering its behavior, ensuring that payment handling always follows the same, trusted code path.

Key Takeaways

  1. Sealed Classes: Once a class is sealed, no class can inherit from it. This is useful when you want to ensure the integrity and finality of the class.
  2. Sealed Methods: A sealed method prevents any further overriding in derived classes, ensuring that critical functionality remains unchanged.
  3. Use Sealed Classes Sparingly: Sealed classes should only be used when you are certain that a class should not be extended. Overuse of sealed classes can limit the flexibility of your codebase.
  4. Performance Benefit: Sealing a class or method can have slight performance benefits since the runtime doesn’t need to check for possible inheritance.
  5. Real-World Applications: Sealed classes and methods are particularly useful in systems where security, stability, and performance are critical, such as payment gateways, networking libraries, and core infrastructure code.

Summary

The sealed keyword in C# is a powerful tool for developers to restrict inheritance and prevent further overrides in class hierarchies. Sealing classes and methods ensures that specific behaviors are protected from being altered, which can help maintain code integrity and security, especially in critical applications. This tutorial covered sealed classes and methods, their characteristics, use cases, and examples, along with their impact in real-world systems like payment processing.

In conclusion, sealing a class or method should be done thoughtfully, with careful consideration of the consequences it will have on the extensibility of your code. When used correctly, it can lead to more robust, stable, and secure software systems.