George Mamaladze

.NET C# tips, tricks, tweaks. Effective use of data structures and algorithms. Clean code.
posts - 11, comments - 15, trackbacks - 0

My Links

News

Archives

Post Categories

All

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

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.

Print | posted on Monday, February 01, 2010 5:26 AM | Filed Under [ C# Language .NET Framework ]

Feedback

Gravatar

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

Great Document created with good observations

Thanks
8/25/2010 5:00 AM | mahesh
Gravatar

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

Really nice one dude!!!
10/21/2010 7:26 AM | Logu
Gravatar

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

You brought up with very good point thanks for your clarification
11/11/2010 3:04 AM | Praveen
Gravatar

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

If however you are writing a framework or code that could be run by downstream developer, you will make them very upset when they cannot extend and modify your classes. Same goes for not declaring public virtual properties and methods. Performance critical code doesn't really belong in a managed language (.NET) IMO. The marginal cost of faster hardware is much less than a future dev wasting time coding around a sealed class.
2/20/2011 7:30 PM | Ryan
Gravatar

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

A class will be usually marked as seal when you have static members, like the Pens class in System.Drawing.
4/2/2011 10:13 PM | Prasanna
Gravatar

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

Very nice - thanks for the great example of a specific reason (in short supply on the subject) for the benefits of the "sealed" keyword.

I have looked and looked and have only EVER been completely FRUSTRATED by the sealed keyword. It has only EVER hampered my efforts, and never (in my experience) enhanced them.

That being said, it seems to me that the problem goes a little bit further than this specific case has shown. Adding the sealed keyword DOES Expose the problem in the case you have provided, because in this case, nothing else sub-classes Class1, but the original code COULD actually be valid (and NOT throw a runtime exception as follows).


---------------------------------------------------
internal interface IInterface1 {}

class Class1 {}

class Class2 : Class1, IInterface1 {}

class Program
{
static void Main(string[] args)
{
//Class1 does not implement IInterface1
Class1 instanceOfClass1 = new Class2();

//However this cast does not lead to compilation error (and SHOULD NOT - because it won't fail now)
IInterface1 someImplementer = (IInterface1)instanceOfClass1;
}
}
---------------------------------------------------

This code would NOT fail. I have not changed the line that threw the runtime exception, and the fact that the EXACT same line could work given the 2 changes I did make explains why the compiler can't complain in the original case.

Again, that being said, if instead, we simply wrote the original code in a more safe manner, it would behave correctly in either case. Specifically:


IInterface1 someImplementer = instanceOfClass1 as IInterface1;
if (someImplementer != null) {
...
}

In this case, it would NOT fail at compile time (or runtime) and would still allow us to override Class1 if we needed to, where sealing it would prevent this behavior. With this in mind, it seem preferrable to me to write safe code described above, rather than sacrificing the ability to take advantage of the basic oop principal of inheritance.

Given this re-casting of the example, my question would be - other than performance reasons, can anyone think of a good, specific use-case for using the sealed keyword?

Thoughts?
8/3/2011 7:49 AM | EJ
Gravatar

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

Yes there are many reasons why not to make classes sealed.
In meanwhile I am also not very big fan of sealed.
But a nullcheck is not the best solution to deal with that I think.

1. Conditionals clutter your code you should prefer type safe code and inheritance over conditionals. If you are dealing in your code with two sorts of objects TypeA and non TypeA objects you will need to make this check every time you invoke a member of TypeA. In this case the clean way of doing that would be to create two different classes or methods one ClassToDealWithTypeA and another ClassToDealWithNonTypeA. In this case you might have only one check at the very beginning when constructing the object graph see http://www.youtube.com/watch?v=4F72VULWFvc

2. AS cast does not allow you to differentiate between the true null and non TypeA objects, but there are also good reasons to use AS cast instead of prefix cast see my another article on that sites.google.com/site/gmamaladze/projects/short-articles/prefix-casting-versus-as-casting-in-c

Regards
George
8/3/2011 9:05 AM | gmamaladze
Gravatar

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

great ! thanks !
1/18/2012 6:13 PM | nisim
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: