I am a huge fan of extension methods and in a past post I have described how one could add useful methods to existing types within the .NET framework. This idea is sound, however, I remember almost within a week of the post Jeff Atwood posted a critique of the extension methods that bordered on hostile (I believe the timing was a complete coincidence).

Upon reading both posts again I realized that there should be additional discussion on Extension Methods within the scope of Interface design. What both posts did not look at was the potential impact of extension methods on the fundamental idea of interfaces in C#, vis-a-vis, having abstract method signatures with implementation code.

So lets look at a simple interface:

    public interface ITalk
    {
        void Shout(string words, bool whisper);
        void Shout(string words);                 //whisper is supposed to be false but an
                                                  //interface cannot implement this solution
    }

So if I am the architect of the interface and want to ensure that when developers use the ITalk.Shout(string words) signature, that the bool whisper parameter is always false, I would be forced to redesign this as a base class because this default value constraint is traditionally only enforceable in a base class.

However, with extension methods another options is made available to me, I can actually spot weld an implementation that forces default values to be used as follows:

    public interface ITalk
    {
        void Shout(string words, bool whisper);
        //I remove the Shout(string words) implementation
    }

    public static class ITalkExtensions
    {
        public static void Shout(this ITalk talk, string words)
        {
            talk.Shout(words, false);
        }
    }

So with the above example we actually solve the issue of using an interface while simultaneously providing a pseudo implementation that will provide default values. This technique also enables us to modify an interface without requiring wholesale updates to users of the the Interface. Our code using ITalk would look like this.

    public class Test1 : ITalk
    {

        #region ITalk Members

        public void Shout(string words, bool whisper)
        {
            throw new NotImplementedException();
        }

        #endregion

    }

In the following example, Test1 inherited ITalk and as you can see there is an extension method available to you.
image

Technorati tags: ,