Extension Methods and inheritance

Remember that extension methods are static methods !

Since their introduction in the Framework, extension methods have been a very simple mean to add functionality into class or on top of interfaces. Without extension methods, there would be no LINQ-style syntax allowing us to chain easily calls such as :

words
.Where(w => w.StartsWith("M"))
.Select(w => w.ToUpper());

The key to this pattern has been described many times and is built on the principle that the extension methods “Where” and “Select” take an IEnumerable<T> (T is string here) as their first input parameter, and return an other IEnumerable<T>. This way, the next call in the chain will use the previous output as its input.

But when implementing an using extension methods, when it comes to inheritance you have to remember that these methods are static ! What I mean here is that the method resolution will occur at compile time and not at runtime. This leads to extension methods having quite the same behaviour as instance methods written using the “new” keyword (as opposed to “overrides”).

Let me explain that with an example. I first define here two interfaces, the second being a specialization of the first.

The two instances of the Baby class are identical, but the extension methods calls are resolved based on the type of the declared variables into which theses instances are stored. One of these instances is a ISoundMaker, and the other one is a ITalker.

Even if the Baby class implements ITalker, when an instance is stored in a variable of type ISoundMaker, the extension method will be the ISoundMaker’s one.

So here for instance the variables soundSong and talkSong have the following values :