Is There Any Way in C# to Override a Class Method with an Extension Method

Is there any way in C# to override a class method with an extension method?

No; an extension method never takes priority over an instance method with a suitable signature, and never participates in polymorphism (GetHashCode is a virtual method).

How to override an existing extension method

UPDATE: This question was the subject of my blog in December of 2013. Thanks for the great question!


You can do this, in a sense. But I should start by talking briefly about the basic design principle of overload resolution in C#. All overload resolution is, of course, about taking a set of methods with the same name and choosing from that set the unique best member to call.

There are many factors involved in determining which is the "best" method; different languages use a different "mixture" of factors to figure this out. C# in particular heavily weights "closeness" of a given method to the call site. If given the choice between an applicable method in a base class or a new applicable method in a derived class, C# takes the one in the derived class because it is closer, even if the one in the base class is in every other way a better match.

And so we run down the list. Derived classes are closer than base classes. Inner classes are closer than outer classes. Methods in the class hierarchy are closer than extension methods.

And now we come to your question. The closeness of an extension method depends on (1) how many namespaces "out" did we have to go? and (2) did we find the extension method via using or was it right there in the namespace? Therefore you can influence overload resolution by changing in what namespace your static extension class appears, to put it in a closer namespace to the call site. Or, you can change your using declarations, to put the using of the namespace that contains the desired static class closer than the other.

For example, if you have

namespace FrobCo.Blorble
{
using BazCo.TheirExtensionNamespace;
using FrobCo.MyExtensionNamespace;
... some extension method call
}

then it is ambiguous which is closer. If you want to prioritize yours over theirs, you could choose to do this:

namespace FrobCo
{
using BazCo.TheirExtensionNamespace;
namespace Blorble
{
using FrobCo.MyExtensionNamespace;
... some extension method call
}

And now when overload resolution goes to resolve the extension method call, classes in Blorple get first go, then classes in FrobCo.MyExtensionNamespace, then classes in FrobCo, and then classes in BazCo.TheirExtensionNamespace.

Is that clear?

Can Extension-Methods overwrite instance methods?

No, you cannot override the instance method with extension methods. Hence, the name 'extension' method, you can only extend the instance methods.

An instance method will always override the extension method.

If you want to force to call the extension method, call it as a regular static method:

ExtMethods.MyMethod(yourClassInstance);

About the why VS doesn't tell you it is a duplicate: actually it can't do that. What if you have an extension method on object. Should VS check all classes and their methods if any method is a duplicate? They simply didn't build the check, it is something you should do yourself.

Create an extension method to override from different classes

Your current approach is OK.

Extension method is the static method too. There won't be any difference at runtime, just a syntax one:

this.myToString()

instead of

Helper.myToString(this)

Since writing extension methods for object isn't a good choice (it will be available for everything), Helper class is preferable.

Overriding Extension Methods

I agree with Michael. Base classes should contain all base functionality Extension methods should, obviously, extend the base functionality. In dynamic languages like Ruby it is often typical to use extension methods to provide addition functionality instead of using subclasses. Basically, extension methods are there to replacing using subclassses, not to replace using base classes.

The only exception to this that I've seen is if you have multiple type that have different class hierachies (like winform controls), you can make a subclass of each that all implement and interface and then extend that interface, thereby giving "base" functionality to a group of different controls, without extending everything like Control or Object.

Edit: answering your second question

I think the compiler will catch this for you.

Override (or shadow) a method with extension method?

No. From MSDN:

You can use extension methods to extend a class or interface, but not to override them. An extension method with the same name and signature as an interface or class method will never be called. At compile time, extension methods always have lower priority than instance methods defined in the type itself.

Extension Method Overriding

As you said, there is no way of just making the extension virtual.

You could implement the entire virtual method pattern yourself through static methods but I have a strong feeling that's not going to be of any practical use to you, it's more of an interesting theoretical solution as the work involved would be prohibitive for something this simple.

If there are a fixed, finite number of possible sub classes you could have the first method have something like:

public static void HelperExtension(this A a)
{
B b = a as B;
if(b != null)
HelperExtension(b);
else
//the rest of the method.
}

You could use a Switch or even a Dictionary<Type, Action<A>> if you have a lot of subclasses, but it would be tedious, hard to maintain, and not support arbitrary inheritors not known at compile time.

Another option is to essentially leverage the compiler's functionality at compile time through the use of dynamic. I strongly advice avoiding it whenever possible, but in this particular case it would allow you to have a single public extension on A, a bunch of private static methods (with a different name) for each sub type, and then a single dispatch call:

public static void HelperExtension(this A a)
{
ExtenstionImplementation((dynamic)a);
}

private static void ExtenstionImplementation(A a){...}
private static void ExtenstionImplementation(B a){...}
private static void ExtenstionImplementation(C a){...}

Can I add an extension method to derived classes that calls protected methods in the base?

Is there any way around this so that I don't have to implement this in every child class?

No, there isn't.

Extension methods are static methods on static classes that only appear (through the magic of intellisense) to "belong" to a type. This means that types need to match exactly (for one).

It also means that they do not belong to the type and don't have access to any protected/private members declared in the type.



Related Topics



Leave a reply



Submit