Extension Methods & Interfaces


Interfaces are used to logically encapsulate definitions for a group of related functionalities, contains only the signatures of methods, properties, events or indexers. On the flip side — “extension methods enable you to ‘add’ methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.” I suppose you already know it. Now the question arises, even if this was somehow ‘technically possible’ … why do you need it ?

A famous man once said “with great power comes great responsibilities” – who said that what is that even mean, don’t matter. I said that because he said it. So now he was famous and getting said by two well known guys. urgh … let’s track this from the beginning…

Don’t extension methods simply hide the behavior that you just can’t see upfront when you’re looking at a class for the first time ? … They might. And that’s why I see them as a responsibility.

So what’s the deal ? Why in the infinite wisdom you want to stick these together ? Interfaces are strictly about declaration and extension methods ought to be implemented ! You might ask why not use abstract base classes ? Good question ! Please follow along…

  1. To answer the question above, sometimes we need a behavior that was also independent of any members’ implementation. From my experience, sometimes you don’t really need another class to implement your interface !
    [ *** hint ! hint ! *** ]
  2. Another way to put it is : Unlike C++, C# cannot take an unknown class type as base class, hence Extension Methods seems to be the right way. ( … with some unique benefits which C++ might not offer )

Enough talking … so for item # 1 above, let me give you an example rather :

I once had a project with multiple modules in it, each would’ve its own configurations. So I came up with following interface :

public interface IConfiguration
{
  // Gets the configuration value by param name
  string GetConfig(string configName);

  // Gets the configuration value by param name
  // and default value is returned if value not found
  string GetConfig(string configName, string defaultVal);
}

And I was done, each module would’ve dedicated class to implement these two functions however it wants. It worked as expected, until one day when I needed to read some config values from *.config files, operating system environment variables etc. These were still configurations, so I did not actually need new class or interface. Adding just a signature in the interface and again leaving it upto each module to implement might be perfectly legal – but wait a second !!!

  1. Did I needed to write same function again and again to read same kind of configurations ?
  2. Would maintaining, tracking or debugging that code be easier ? Of course not !
  3. What happened to DRY ?

I simply needed to extend IConfiguration interface to support it. There you go ! I needed to write it once and make it accessible to all implementations of IConfiguration, that’s it !

So I added an extension method in the same folder called “Common” where I had IConfiguration.cs :

public static class Extensions
{
  // Some sample extension method ...
  public static string JoinStrings(this string input, string parameter)
  {
    return (input + parameter);
  }

  // returns system configuration, notice first parameter !
  public static string GetSysConfig(this IConfiguration config, string param)
  {
    return "system parameter value";
  }

  // returns system configuration with default value, notice first parameter !
  public static string GetSysConfig(this IConfiguration config, string param, string default)
  {
    return "system parameter value or default" ?? defaultValue;
  }
}

Cheers !

Advertisements

Published by

Aarsh Talati

Software Developer

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s