Sealed method in C#

Well, you are testing with only two levels of inheritance, and you are not getting to the point that you're "further overriding" a method. If you make it three, you can see what sealed does:

class Base {
   public virtual void Test() { ... }
}
class Subclass1 : Base {
   public sealed override void Test() { ... }
}
class Subclass2 : Subclass1 {
   public override void Test() { ... } // Does not compile!
   // If `Subclass1.Test` was not sealed, it would've compiled correctly.
}

A sealed class is a class which cannot be a base class of another more derived class.

A sealed method in an unsealed class is a method which cannot be overridden in a derived class of this class.

Why do we use sealed methods? What are the advantages of sealed methods?

Well, why do you use virtual methods? To provide a point at which behaviour of a class can be customized. So why do you use sealed methods? To provide a point at which you are guaranteed that no further changes will occur in the behaviour of any derived class with respect to this method.

Points where the behaviour of a class can be customized are useful but dangerous. They are useful because they enable derived classes to change behaviour of the base class. They are dangerous... wait for it... because they enable derived classes to change behaviour of the base class. Virtual methods basically allow third parties to make your classes do crazy things that you never anticipated or tested.

I like writing code that does what I anticipate and what I tested. Sealing a method allows you to continue to allow parts of the class to be overridden while making the sealed methods have guaranteed, testable, stable behaviour that cannot be further customized.


Well, you'd only use "sealed" on a method if you didn't want any derived classes to further override your method. Methods are sealed by default, if they're not declared as virtual and not overriding another virtual method. (In Java, methods are virtual by default - to achieve "default" C# behaviour you have to mark a method as final.)

Personally I like to control inheritance carefully - I prefer whole classes to be sealed where possible. However, in some cases you still want to allow inheritance, but ensure that some methods aren't overridden further. One use might be to effectively template the method, e.g. for diagnostics:

public sealed override void Foo(int x)
{
    Log("Foo called with argument: {0}", x);
    FooImpl(x);
    Log("Foo completed");
}

protected abstract void FooImpl(int x);

Now subclasses can't override Foo directly - they'd have to override FooImpl, so our behaviour will always be executed when other code calls Foo.

The templating could be for other reasons of course - for example to enforce certain aspects of argument validation.

In my experience sealed methods aren't used terribly often, but I'm glad the ability is there. (I just wish classes were sealed by default, but that's another conversation.)

Tags:

C#

Sealed