As outlined in my previous post
, there are three versioning problems with extension methods:
- The behaviour of your program can change unexpectedly
- The compiler does not warn you about the changes
- Even if the compiler did warn you, your ability to respond is limited
In this post, I’ll outline a suggested solution that fixes all three problems. This will be a lengthy post, so please bear with me (or skip to the conclusion below if you can’t wait ;-)Introduction
I suggest that:
Extension methods should belong to interfaces. Think of it as defining an "extension contract", a defined set of methods which can be provided as extension methods.
For example, here’s an extension method called Foo
, which belongs to interface IFooable
public static class Extender: IFooable
public static void Foo(this Thing t)
public interface IFooable
That’s all standard C# 3, except for the bit in bold, which is new. It means, "The static class Extender provides extension methods which implement IFooable
(The definition of interface IFooable
is perfectly ordinary C#, there's nothing new there.)Details
Every extension method is now associated with a particular “contract for functionality” (the contract represented by the interface). By associating extension methods with defined contracts, we can solve all of the problems noted above.
When the compiler hits this line...a.Foo()
...it identifies all the applicable methods called Foo 
. Say it finds an instance method and an extension method, both called Foo
- If they both belong to the same interface, the compiler can assume that the instance version is the best choice. The class is, in effect, “overriding” an extension method with a specialized alternative. (In the interests of brevity, I won’t dwell on this point, but please leave a comment below if I haven’t made myself clear.)
- If the methods do not belong to the same interface, the compiler raises an error . The call is ambiguous because the two methods belong to different contracts for functionality.
Let’s see how this would work in practice. Consider my previous example
of an extension method for strings, called Contains
. If you wrote that method, you’d have to associate it with an interface. You’d write something like this:
public static class StringExtender: IContainable
public static bool Contains
(this string source,
public interface IContainable
bool Contains(string value);
Now, imagine that Microsoft release their own Contains
method for strings, which is incompatible with yours. The compiler will look at both methods to see which interface they belong to. Microsoft’s Contains may belong to an interface defined by Microsoft
or, since its an instance method, it may not belong to any interface at all. In any case, it does not belong to your
interface. Therefore, the compiler knows that it’s not a substitute for your Contains
After detecting that the methods belong to different contracts (interfaces), the compiler raises an error. Fortunately, using interfaces offers us a convenient way to tell the compiler which method we actually want, and thereby resolve the error. Simply include the name of the interface which defines the method you want to call. Or, for instance methods with no interface, use the name of the class. Like this:
string s = "abc";
string t = "a";
//calls your extension method
//calls Microsoft's instance method
This hypothetical syntax looks a lot like the existing operator for casting types
, except it looks like it's casting methods
– which it is, in a way.
To tie all this back to my previous post
, the current C# spec allows you to force the call to go to the extension method by writing StringExtender.Contains(s, t).
That's like s.(IContainable)Contains(t)
. The current C# spec does not
support the opposite, s.(string)Contains(t)
, in any way.Conclusion
There are versioning problems with extension methods. The problems can be solved by making extension methods belong to well-defined contracts for functionally, using standard C# interfaces to define those contracts.
Here is each of the problems I originally stated, and its solution:Problem:
The behaviour of your program can change unexpectedlySolution:
There are no unexpected breakages, because instance methods only
replace extension methods which belong to the same contract (interface).Problem:
The compiler does not warn you about the changesSolution:
The compiler detects any ambiguity, and warns you.Problem:
Even if the compiler did warn you, your ability to respond is limited.Solution:
You can force the call in either direction: to the extension method or to the instance.
Stay tuned for my next post
, in which I’ll outline some groovy side-effects of this proposal... (and also see my later followup here
 Is there a performance cost, at compile time, in identifying all the possible methods? In the current C# 3 spec, the compiler doesn’t even bother looking for extension methods if an instance one exists. In my suggested approach, it always has to check for extension methods. I would guess that my solution has some compile-time cost, but that the cost would be acceptable on modern hardware.
 Or, as I suggested in my previous post, perhaps the compiler could just raise a warning instead, and then go ahead and choose the instance method. That’s not my preferred approach, but it would keep the behaviour in line with Microsoft’s current spec for C# 3 – i.e. the compiler always does what the current spec says, with the difference being it does raise a warning when it knows it's doing something dangerous.
 Even if Microsoft gave their interface the same name as yours, the compiler could still tell the difference, just like it does right now for same-named interfaces from different namespaces.