Geeks With Blogs
George Mamaladze .NET C# tips, tricks, tweaks. Effective use of data structures and algorithms. Clean code.

C# Tweaks - Why to use the sealed keyword on classes

 

The sealed keyword is one of the very seldom used modifiers in C#. Probably most of you know what it is for, but only several developers ever used it.

 

See C# Programmers Guide if you are not sure you remember what the keyword is good for: http://msdn.microsoft.com/en-us/library/88c54tsw(VS.71).aspx

 

Why shell I use it?

Most popular, but not really most important motivation is the performance - JIT compiler can produce more efficient code by calling the method non-virtually. I remember someone even made performance measurements, but I think that the real performance gain highly depends on algorithms in a specific use case.

 

The vast majority of .NET programmers let their classes “unsealed” without even considering making them sealed. If a class was not designedly made inheritable it is very probably even impossible to inherit from it and override members reasonably. On the other hand overriding members of the class which was not designed to be overridden might cause unpredictable results.

 

When a class is originally sealed, it can change to “unsealed” in the future without breaking compatibility.

 

Something new I’ve discovered recently

Recently I was refactoring some component with multiple classes making intensive use of inheritance. During cleanup I changed all leaf classes in inheritance tree, the classes which can not be inherited anymore, to be sealed. I was sure it will not break compatibility, but the next compile failed.

 

The reason was a bug, which became visible only after I made some class sealed to compile time, instead of throwing exception during execution. This sample demonstrates the simplified version of my situation:

interface IInterface1 {}

 

class Class1 {}

 

class Program

{

    static void Main(string[] args)

    {

        //Class1 does not implement IInterface1

        Class1 instanceOfClass1 = new Class1();

 

        //However this cast does not leads to compilation error

        IInterface1 someImplementer = (IInterface1)instanceOfClass1;

    }

}

 

Class1 does not implement IInterface1, however the cast of an instance of the Class1 to IInterface1 does not lead to compilation error. The reason is that theoretically some inherited class of the Class1 might implement this interface.

 

Now let’s make Class1 sealed. Now the compiler will see that Class1 can be only Class1 “itself” (and its base classes if applicable) and it does not implement interface IInterface1.

 

internal interface IInterface1 {}

 

sealed class Class1 {}

 

class Program

{

    static void Main(string[] args)

    {

        //Class1 does not implement IInterface1

        Class1 instanceOfClass1 = new Class1();

 

        //However this cast does not leads to compilation error

        IInterface1 someImplementer = (IInterface1)instanceOfClass1;

    }

}

 

Following compilation error will occur:

Cannot convert type 'Class1' to 'IInterface1'

 

So using sealed keyword brings not only performance win and additional code access security but also helps to write bug free code, making better use of the .NET type safety.

 

My recommendation: Always declare a new class as sealed until you are writing an abstract class or a class which must be inherited per design. Most classes in a real application (except you are writing a widely used library) can be made sealed.

 

P.S. You can apply the sealed keyword not only to classes but also to some members. I am going to post about that as well.

Posted on Monday, February 1, 2010 5:26 AM C# Language , .NET Framework | Back to top

Copyright © George Mamaladze | Powered by: GeeksWithBlogs.net