views:

126

answers:

2

I have written some extension Methods to convert an IEnumerable and an IList into a string. Now, as IList inherits from IEnumerable, I have to name them differently.

I just wonder if there is a way to avoid that? Can I have an extension Method on an IEnumerable and then a different one on an IList with the same name and the same signature? Kinda like an override, except that Extension methods are of course static.

I would just like to use a more efficient method body on a List without having to have a second Method name.

And yes, I know that in this specific case, I should run a profiler first to really see if the second method is better, but I'm interested if it's generally possible to override extension methods in derived classes.

+3  A: 

Why don't you do what the BCL does, and attempt a downcast within the same method?

Something lik this:

public static string Foo<T>(this IEnumerable<T> source)
{
    var list = source as IList<T>;
    if(list != null)
    {
        // use more efficient algorithm and return
    }
    // default to basic algorithm
}

If you absolutely must have two separate extension methods with the same name, you can have them in classes in two different namespaces, but that would mean that you could never use them both in the same code file, so that's hardly optimal.

Mark Seemann
Interesting approach, that would work - do you know where the BCL does that?
Michael Stum
`Enumerable.Count()` does that - it checks for `ICollection<T>` and uses `.Count` as a shortcut.
Marc Gravell
Enumerable.Count<TSource> does it...
Mark Seemann
+2  A: 

Daniel Cazzulino recently blogged about mocking extension methods and, within the post, described his method for not only applying a namespace-like grouping to related extension methods but also described how to, essentially, implement extension properties. Here's the blog post. The awesomeness abounds within.

Essentially, you encapsulate related methods within an object and return an instance from an extension method:

public interface ISecurity
{
    Permissions GetPermissions(Uri resource);
}

public static class SecurityExtensions
{
    public static ISecurity Security(this IPerson person)
    {
       return new SecurityImpl(person);
    }
}

You can use this technique to "namespace" your extension methods.

Will