tutorial - when to use extension methods




Extension interface patterns (8)

A decent way to think about this is that instance methods are something done by the object, while extension methods are something done to the object. I am fairly certain the Framework Design Guidelines say you should implement an instance method whenever possible.

An interface declares "I care about using this functionality, but not how it is accomplished." That leaves implementers the freedom to choose the how. It decouples the intent, a public API, from the mechanism, a class with concrete code.

As this is the main benefit of interfaces, implementing them entirely as extension methods seems to defeat their purpose. Even IEnumerable<T> has an instance method.

Edit: Also, objects are meant to act on the data they contain. Extension methods can only see an object's public API (as they are just static methods); you would have to expose all of an object's state to make it work (an OO no-no).

The new extensions in .Net 3.5 allow functionality to be split out from interfaces.

For instance in .Net 2.0

public interface IHaveChildren {
    string ParentType { get; }
    int ParentId { get; }

    List<IChild> GetChildren()
}

Can (in 3.5) become:

public interface IHaveChildren {
    string ParentType { get; }
    int ParentId { get; }
}

public static class HaveChildrenExtension {
    public static List<IChild> GetChildren( this IHaveChildren ) {
        //logic to get children by parent type and id
        //shared for all classes implementing IHaveChildren 
    }
}

This seems to me to be a better mechanism for many interfaces. They no longer need an abstract base to share this code, and functionally the code works the same. This could make code more maintainable and easier to test.

The only disadvantage being that an abstract bases implementation can be virtual, but can that be worked around (would an instance method hide an extension method with the same name? would it be confusing code to do so?)

Any other reasons not to regularly use this pattern?


Clarification:

Yeah, I see the tendency with extension methods is to end up with them everywhere. I'd be particularly careful having any on .Net value types without a great deal of peer review (I think the only one we have on string is a .SplitToDictionary() - similar to .Split() but taking a key-value delimiter too)

I think there's a whole best practice debate there ;-)

(Incidentally: DannySmurf, your PM sounds scary.)

I'm specifically asking here about using extension methods where previously we had interface methods.


I'm trying to avoid lots of levels of abstract base classes - the classes implementing these models mostly already have base classes. I think this model could be more maintainable and less overly-coupled than adding further object hierarchies.

Is this what MS have done to IEnumerable and IQueryable for Linq?


Another way to solve this is to use a generic method for GetRequests

IEnumerable<T> GetRequests<T>(int maxRequestNumber);

But the class who invokes GetRequest should know what is the type they are expecting. If they Expect IRequestOld/IRequestNew, they should pass it while calling GetRequests.

IRequestOld request = GetRequest<RequestOld>(maxRequestNumber);
IRequestNew request = GetRequest<RequestNew>(maxRequestNumber);

An example program

class Program
{

    public static void Main()
    {
        Number n = new Number();
        IOne one = n.GetNumberObject<One>();
        one.PrintOne();
        ITwo two = n.GetNumberObject<Two>();
        two.PrintTwo();
    }

    public interface INumbers
    {
        T GetNumberObject<T>() where T : new();
    }
    public class Number : INumbers
    {
        public T GetNumberObject<T>() where T : new()
        {
            return new T();
        }
    }

    public interface IOne
    {
        void PrintOne();
    }
    public interface ITwo
    {
        void PrintTwo();
    }

    class One : IOne
    {
        public void PrintOne()
        {
            Console.WriteLine("One");
        }
    }
    class Two : ITwo
    {
        public void PrintTwo()
        {
            Console.WriteLine("Two");
        }
    }
}

I think the best thing that extension methods replace are all those utility classes that you find in every project.

At least for now, I feel that any other use of Extension methods would cause confusion in the workplace.

My two bits.


I think the judicious use of extension methods put interfaces on a more equatable position with (abstract) base classes.


Versioning. One advantage base classes have over interfaces is that you can easily add new virtual members in a later version, whereas adding members to an interface will break implementers built against the old version of the library. Instead, a new version of the interface with the new members needs to be created, and the library will have to work around or limit access to legacy objects only implementing the original interface.

As a concrete example, the first version of a library might define an interface like so:

public interface INode {
  INode Root { get; }
  List<INode> GetChildren( );
}

Once the library has released, we cannot modify the interface without breaking current users. Instead, in the next release we would need to define a new interface to add additional functionalty:

public interface IChildNode : INode {
  INode Parent { get; }
}

However, only users of the new library will be able to implement the new interface. In order to work with legacy code, we need to adapt the old implementation, which an extension method can handle nicely:

public static class NodeExtensions {
  public INode GetParent( this INode node ) {
    // If the node implements the new interface, call it directly.
    var childNode = node as IChildNode;
    if( !object.ReferenceEquals( childNode, null ) )
      return childNode.Parent;

    // Otherwise, fall back on a default implementation.
    return FindParent( node, node.Root );
  }
}

Now all users of the new library can treat both legacy and modern implementations identically.


Overloads. Another area where extension methods can be useful is in providing overloads for interface methods. You might have a method with several parameters to control its action, of which only the first one or two are important in the 90% case. Since C# does not allow setting default values for parameters, users either have to call the fully parameterized method every time, or every implementation must implement the trivial overloads for the core method.

Instead extension methods can be used to provide the trivial overload implementations:

public interface ILongMethod {
  public bool LongMethod( string s, double d, int i, object o, ... );
}

...
public static LongMethodExtensions {
  public bool LongMethod( this ILongMethod lm, string s, double d ) {
    lm.LongMethod( s, d, 0, null );
  }
  ...
}


Please note that both of these cases are written in terms of the operations provided by the interfaces, and involve trivial or well-known default implementations. That said, you can only inherit from a class once, and the targeted use of extension methods can provide a valuable way to deal with some of the niceties provided by base classes that interfaces lack :)


Edit: A related post by Joe Duffy: Extension methods as default interface method implementations


Would not make sense. An Interface is a contract with the public that you support those methods and properties. Stick with abstract classes.


You can hide the implementation of an interface by explicitly stating the interface name before the method name:

public interface IInterface {
    public void Method();
}

public class A : IInterface {
    public void IInterface.Method() {
        // Do something
    }
}

public class Program {
    public static void Main() {
        A o = new A();
        o.Method(); // Will not compile
        ((IInterface)o).Method(); // Will compile
    }
}

Non Public Members for C# Interfaces

If an interface is internal, all its members will be internal to the assembly. If a nested interface is protected, only the subclasses of the outer class could access that interface.

Internal members for an interface outside of its declaring assembly would be pointless, as would protected members for an interface outside of its declaring outer class.

The point of an interface is to describe a contract between a implementing type and users of the interface. Outside callers aren't going to care and shouldn't have to care about implementation, which is what internal and protected members are for.

For protected members that are called by a base class, abstract classes are the way to go for specifying a contract between base classes and classes that inherit from them. But in this case, implementation details are usually very relevant, unless it's a degenerate pure abstract class (where all members are abstract) in which case protected members are useless. In that case, go with an interface and save the single base class for implementing types to choose.


Pseudo-multiple-inheritance with extension methods on interfaces in C#?

The problem that I see with building interface capability via extension methods is that you are no longer actually implementing the interface and so can't use the object as the interface type.

Say I have a method that takes an object of type IBar. If I implement the IBar interface on class Foo via extension methods, then Foo doesn't derive from IBar and can't be used interchangeably with it (Liskov Substitution principle). Sure, I get the behavior that I want added to Foo, but I lose the most important aspect of creating interfaces in the first place -- being able to define an abstract contract that can be implemented in a variety of ways by various classes so that dependent classes need not know about concrete implementations.

If I needed multiple inheritance (and so far I've lived without it) badly enough, I think I'd use composition instead to minimize the amount of code duplication.