How to deal with a sealed class when I wanted to inherit and add properties
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Needing extra properties on a class that is sealed is a common design problem in enterprise codebases. Since inheritance is blocked by intent, the safe path is to extend behavior through composition instead of subclassing. This article shows practical patterns in C# that preserve the original contract and still let you add metadata and logic.
Why a Class Is Sealed in the First Place
Libraries seal classes to protect invariants, simplify versioning, and avoid unsupported overrides. If you force inheritance through workarounds, upgrades become fragile and behavior can drift from documentation. It is better to treat the sealed type as a stable dependency and build extension points around it.
A basic sealed type looks like this:
Because this type cannot be inherited, your extension model moves to wrappers, adapters, and helper APIs.
Add Properties With a Wrapper Object
The most direct approach is a wrapper that stores the sealed instance and your additional properties. This gives you explicit ownership over validation, serialization shape, and lifecycle.
This pattern is usually enough when you need new state and can control call sites.
Use an Adapter Interface for Flexible Behavior
If your service layer needs abstraction, define an interface and expose the sealed type through an adapter. This keeps business logic independent from vendor classes and improves testability.
An adapter is especially useful when multiple token providers exist and your domain needs one uniform contract.
Add Utility Behavior With Extension Methods
Extension methods can make usage cleaner when you need computed behavior rather than stored properties. They are not substitutes for added state, but they are good for shared formatting and validation helpers.
Use wrappers for data, adapters for abstraction, and extension methods for convenience behavior. Combined thoughtfully, these patterns cover most sealed-class extension needs.
Common Pitfalls
- Treating a wrapper as a drop-in subtype, which causes friction where exact base type signatures are required.
- Hiding the original sealed object completely even though integration code still needs direct access.
- Letting wrapper types accumulate unrelated fields and become giant transport objects.
- Using extension methods to imitate stateful properties, which is impossible and misleading.
- Skipping constructor validation on added properties, allowing invalid metadata to spread.
Summary
- Sealed classes intentionally block inheritance, so extension should use composition patterns.
- Wrapper types are the cleanest way to add new properties.
- Adapter interfaces decouple domain logic from external sealed classes.
- Extension methods are helpful for computed helpers, not instance state.
- Respecting the sealed contract generally improves maintainability and upgrade safety.

