C# Extension Methods. Abuse of static or not? Pros and Cons

Recently in my projects I've been finding more use for extension methods in C#. If you're not familiar with extension methods, they go something like this.

public static class Extensions
{
  public static string AsScoreString(this MyClassA myclass) 
  {
      return myclass.Foo.ToString() + " points!";
  }
}

public class MyClassA
{
  public int Foo { get;set; }
}

Basically some syntax sugar. Instead of writing 'Extensions.AsScoreString(myclassInstance)', you get to write 'myclassInstance.AsScoreString()'. To me, the later reads a lot more clearly. However, does the fact 'AsScoreString' is now not within the 'MyClass' object itself, muddy the waters or improve things? Here is the code for a simple (but arbitrary) use.

# Example of use

public class Foo
{
 public MyClassA MyObjectA { get;set; }
 public MyClassB MyObjectB { get;set; }
 
 public string Execute()
 {
   string score = MyObjectA.AsScoreString();
   MyObjectB = MyObjectA.ToMyClassB();
   return score;
 }
}

public class MyClassB
{
  public float Bar { get;set; }
}

public static Extensions
{
  public static MyClassB ToMyClassB(this MyClassA myclassA)
  {
    MyClassB result = new MyClassB();
    result.Bar = myclassA.Foo;
    return result;
  }
}

Although it is just a 'nice to have', I've found them very useful for various reasons However they can make things confusing for the flow of code etc. Here are a few of the pros and cons I've come up with whilst using them in different scenarios.

# Pros

# Code Readability

First and foremost, readability can be improved quite a bit if your extension methods are well named. Lets say you want to convert from one data structure to another like the above example shows. For someone skimming over a code base, whatthe code is doing is conveyed very quickly whilst hiding the howaway from either data structure, making them also clean and easy to read.

# Structural Separation

For functionality like conversion between one data structure and another that represents same information, you could  use a Decorator pattern, why bother with extension methods? Using a Decorator would tie data structure 'MyClassB' to 'MyClassA' which may not be desirable. If I wanted to use the MyClassB data structure in another library, I would take a dependency on 'MyClassA' with me. Having an extension function to perform this operation within a library that needs the conversion, avoids this dependency, gives me clean syntax and leaves the original data structures untouched. A Factory could also achieve this independent conversion, but now messes the readability of the conversion step itself with the factory object in the middle.

# Avoids Relying on Internal State

Since these methods are static, they can't rely on internal state of say a factory (or other) object to help with the logic. This obviously has it's pros and cons (and ways out), but I have found this to be mostly a pro as functionality is contained and isolated away from various changes being made to a system.

# Cons

# I See static People

This grates with me a lot and is the source of why I am a bit wary of the over use of extension methods. Seeing so many statics screams at me that I am missing an object or design pattern. Other times however, these additional objects or interfaces add a lot of friction to the development process.

# No Internal State

Like many things, it's a double edged sword. One thing I have come across while using extension methods is the unavailability of techniques like Dependency Injection (DI) and Inversion Of Control (IoC). Since these methods are in a static class as well as being a static method, I can't use IoC like in other areas of my code.

# Where's that code going?

If you haven't got access to the source of the projects you are working on, extension methods can make the flow of code feel very confusing, jumping from seemly unrelated static extension classes and back. Also while reading the simpler code can leave you a bit worried that you don't know what the extension method is doing. This can give the feeling of 'a bit too much magic' and I don't like 'magic' in programming.

# Conclusion

Extension methods are very useful. However, can be easily abused. Although I do use them, I try to be aware that they are can be a symptom of problems with design depending on the situation.

Tags