The trick here is that interfaces can have extra methods tacked on. In C# we do this using extension methods. Here is a basic example:
public interface IFoo
{
int GetFoo();
}
public class Foo : IFoo
{
public int GetFoo()
{
var foo = ... // does something to get a foo
return foo;
}
}
public class Program
{
public static void Main()
{
IFoo theFoo = new Foo();
theFoo.PityTheFoo(); // wait, what?
}
}
Now at this point I can hear you saying "Amy! Hold on! IFoo
doesn't have a method that does any kind of pitying!" And you would be right. Pretend for a moment that you don't own the source code for IFoo
. How can you add a method to IFoo
? Or, suppose you do own the source for IFoo
, and want to add a method without having to modify every class that implements that interface?
This is where extension methods come in:
public static class FooExtensions
{
public static void PityTheFoo(this IFoo foo)
{
// pities the foo
}
}
Note the this
keyword inside the function declaration. That indicates this is an extension method. It tacks our PityTheFoo
method onto the interface. Classes that implement the IFoo
interface do not need to implement PityTheFoo()
. If you had one hundred different Foo
classes, all implementing this interface, none of them will require modification.
Extension methods aren't part of the inheritance chain. When the compiler reaches the commented line in Program
, this is what it "pretends" the code looks like:
public class Program
{
public static void Main()
{
IFoo theFoo = new Foo();
FooExtensions.PityTheFoo(theFoo);
}
}
Why would we want this?
- You don't own the interface, but want to add operations to it.
- You own the interface, but the numerous classes that implement that interface can share the same implementation, sort of like they inherited it.
- The interface might be part of a library. If you add a method to it, people who use your library will find their code broken until they add the method to their classes. Extension methods let you avoid the breaking change.