.Net application development specialists
asp.net, c#, vb.net, html, javascript, jquery, html, xhtml, css, oop, design patterns, sql server, mvc and much more
contact: admin@paxium.co.uk

Paxium is the company owned by myself, Dave Amour and used for providing IT contract development services including


  • Application development - Desktop, Web, Services - with Classic ASP, Asp.net WebForms, Asp.net MVC, Asp.net Core
  • Html, Css, JavaScript, jQuery, React, C#, SQL Server, Ado.net, Entity Framework, NHibernate, TDD, WebApi, GIT, IIS
  • Database schema design, implementation & ETL activities
  • Website design and hosting including email hosting
  • Training - typically one to one sessions
  • Reverse Engineering and documentation of undocumented systems
  • Code Reviews
  • Performance Tuning
  • Located in Cannock, Staffordshire
Rugeley Chess Club Buying Butler Cuckooland Katmaid Pet Sitting Services Roland Garros 60 60 Golf cement Technical Conformity Goofy MaggieBears Vacc Track Find Your Smart Phone eBate Taylors Poultry Services Lafarge Rebates System Codemasters Grid Game eBate DOFF

Sealed Classes and Extension Methods

Have you ever been working with someone elses code and needed to add functionality to a class but the code author has unkindly created their class as sealed?

Not nice eh?  I have seen colleagues working with such controls in asp.net and hooking into the rendered html and modifying that just in time with string manipulation!

Thers is a neater way of extending such sealed classes and under the hood its all smoke and mirrors but it looks good and works well and that's all that matters.

What I am talking about is Extension methods.

Extension methods allow you to seemingly add new methods to existing classes so lets look at some examples and see how this works.

Consider the following class:

    public sealed class Person
    {
        public void PayTaxes()
        {
            Console.WriteLine("I am paying my taxes");
        }
 
        public void Eat()
        {
            Console.WriteLine("Munch munch");
        }
    }


This class is sealed but suppose we wanted to give our person some musical abilities and enable him to play the piano.

Well normally we might create a sub class called PianoPlayer which inherited Person and simply added a PlayPiano method or two.  Not possible when the class is sealed though.  Therefore there is some trickery built into the compiler which allows us to achieve the same kind of result even though the class is sealed.

What we need to do is write a static class as follows:

    public static class MusicAbilities
    {
        public static void PlayPiano(this Person p)
        {
            Console.WriteLine("Hey I am playing the piano!");
        }
 
        public static void PlayPiano(this Person p, string songName)
        {
            Console.WriteLine("Hey I am playing \"" + songName + "\"");
        }
    }


So what we do then is create a new class with a sensible name - a name which describes what abilities we are adding.  The class has to be static.  The static keyword when used with a class just means that the class contains nothing but static members and so you cannot create an instance of this.

We then write the methods we require to be added to our sealed class.  These also need to be static and the first parameter of the method must be the type we are extending.  It must also be preceded with a "this" keyword.  The p in our example is of course just a variable name.

And that is all we need to do.  We can now run this code:

    class Program
    {
        static void Main(string[] args)
        {
            Person dave = new Person();
 
            dave.PayTaxes();
            dave.Eat();
 
            dave.PlayPiano();
            dave.PlayPiano("I am like a bird");
 
            Console.Read();
        }
    }


The output from running this will then look like this:

 And if we look at our intellisense in Visual Studio we see the following:

So our class is behaving just as if we really have given it new methods.  Now I'm pretty sure that under the hood there is some smoke and mirrors going off but that doesn't really matter as long as it works.

We can even add these methods to intrinsic classes.  Lets give musical abilities to a SqlConnection object!  Microsoft have made this class sealed so we can't extend it but with extension methods its easy - we just add another method to our static MusicAbilities class which refers to a SqlConnection as follows:

    public static class MusicAbilities
    {
        public static void PlayPiano(this Person p)
        {
            Console.WriteLine("Hey I am playing the piano!");
        }
 
        public static void PlayPiano(this Person p, string songName)
        {
            Console.WriteLine("Hey I am playing \"" + songName + "\"");
        }
 
        public static void PlayPiano(this System.Data.SqlClient.SqlConnection s)
        {
            Console.WriteLine("Hey I am playing the piano!");
        }
    }


We can then run this:

    class Program
    {
        static void Main(string[] args)
        {
            System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection();
 
            conn.PlayPiano();
 
            Console.Read();
        }
    }


And that will work fine.

Now supposing our method needs to interact with other class members?  Well we can do this since our extension method receives a reference to the class we are extending.  For example we can do this:

        public static void PlayPiano(this System.Data.SqlClient.SqlConnection s)
        {
            Console.WriteLine("Hey I am playing the piano! Also my PacketSize is " + s.PacketSize.ToString());
        }


So this works fine and we get the following output:

However there is a snag. Consider the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace StaticClasses
{
    class Program
    {
        static void Main(string[] args)
        {
            Person dave = new Person();
 
            dave.PayTaxes();
            dave.Eat();
 
            dave.PlayPiano();
            dave.PlayPiano("I am like a bird");
 
            Console.Read();
        }
    }
 
    public sealed class Person
    {
        private int legs = 2;
 
        public void PayTaxes()
        {
            Console.WriteLine("I am paying my taxes");
        }
 
        public void Eat()
        {
            Console.WriteLine("Munch munch");
        }
    }
 
    public static class MusicAbilities
    {
        public static void PlayPiano(this Person p)
        {
            Console.WriteLine("Hey I am playing the piano! I also have " + p.legs.ToString() + " legs");
        }
 
        public static void PlayPiano(this Person p, string songName)
        {
            Console.WriteLine("Hey I am playing \"" + songName + "\"");
        }
 
        public static void PlayPiano(this System.Data.SqlClient.SqlConnection s)
        {
            Console.WriteLine("Hey I am playing the piano!");
        }
    }
}
 


This code won't even compile as it says that:

'StaticClasses.Person.legs' is inaccessible due to its protection level


Changing this to protected too gives the same result but with an extra error message since declaring a protected field in a sealed class makes no sense! So our reference passed in to our extension method appears to be just a normal reference.  In other words our extension method is not really running in the context of the actual sealed class otherwise it would be able to access the legs field.  So I guess this is the smoke and mirrors I was hinting at.

So in summary Extension methods can be useful but should generally be a last resort and only used with sealed classes.  If a class is not sealed then simply sub class it.  You can also consider extending a class using composition but that will be in another article.