C# Extension methods

Extending a type is an important thing and is often done. The reason maybe repeating code multiple times and you want to have it generalized into a method that belongs to a type. Or, a programmer from another programming language may need to add a method to a specific class to ease in the programming in C# and be programming like that other language.

Extension methods:

More often that not you end up wanting to extend a code you have no control over, maybe from another library. This is also a good practice to separate concerns of code. You may be doing repetitive work on an object in which you dreamt that the object had the functionality you wanted already.

Extension methods come to the rescue. In fact, the popular .NET Linq uses extension methods to do their work.

Let’s start:

public class Testo
{
	protected int x;

	private void DoSomething()
	{
		x += 10;
	}
}

Here there is a class I cannot add something to. Now I create an extension method in another class called TestoExtensions:

public static class TestoExtensions
{
	public static void Do(this Testo testo)
	{
		// Do something
	}
}

Here is a static class with a static method that has a rather interesting syntax this in the parameter declaration. The this must be the first argument. This Do method takes no argument even though there is one in the signature. Now this is an extension method. You can call it as you were calling a normal method.

Note that the class holding the extension method must be marked static because of single responsibility principle as well as because the compiler is doing somethings behind the scenes to make this work.

Extension methods can have overloads.

Note that even though you can extend a class, operator overloading extension methods are not currently possible.

Extension method on generic classes:

It is possible to add extension methods to generic classes having one more generic types. Let’s make the Testo class above take T:

public class Testo<T>

Now we need to change the signature of the extension method to accomodate the changes in the target class.

public static void Do<T>(this Testo<T> testo)
{
	// Do something object
}

Note that the extension method will also need to be generic. This method will apply to all instances of the class of any generic type.

Here is something you will like a lot. You can have special extension methods on specific types. Like so:

public static void DoInt(this Testo<int> testo)
{
	// Do something int
}

public static void DoString(this Testo<string> testo)
{
	// Do something string
}

Here those 2 methods are only existent on their respective types. Note that I did not make the method take a generic type parameter as I don’t need to. The first DoInt can only be called on Testo<int> and the same is true for any other type.

You can also make the actual extension methods generic, taking a generic that has nothing to do with the class like so:

public static IDictionary<T, X> ToDictionary<T, X>(this Testo<T> testo)
{
	// Do something
	return null;
}

Here there is a method that takes in 2 generic type parameters which is fine. However calling the above method has a caveat where you have to put the generic type parameter in, the one used by Testo<T> like so:

var tString = new Testo<string>();
tString.ToDictionary<string, int>();

The same can be done on interfaces.

Extending object:

You can extend object as you can for any class. Here I will make a utility method for me just as an application of this article:

public static string Info(this object obj)
{
	if (obj == null) throw new ArgumentNullException();

	var type = obj.GetType();
	return $"Name: {type.Name}, Abstract: {type.IsAbstract}, Generic: {type.IsGenericType}";
} 

Note the check for null, here is an important thing to know. Extension methods can be called on null references. It is your job as a developer to check for null.

Limiations of extension methods:

Extensions methods are defined in classes and so in order to use them, you must be using the namespace the extension methods are in.

Another thing, if a class/interface has a method named the same name as an extension method and both are in the same context. The extension method will have lower priority. In other words, the extension is not even recognised by the compiler.

Now I tested the latter limiation to see if a more specialized generic extension method has priority over extension methods defined by the original type. The result is extension methods have lower priority under all circumstances.

Another limitation is the fact that extension methods cannot access internal members of a type directly, you will need to use reflection to do that.

Using reflection on extension methods:

Now what the compiler does with extension methods? Each extension method will get the ExtensionAttribute from the System.Runtime.CompilerServices namespace. So if you are looking for extension methods, look for this attribute.

How are extension methods used:

The Linq library of the .NET standard here utilizes extension methods heavilly. You can view the source code here: https://github.com/dotnet/runtime/tree/master/src/libraries/System.Linq

Why not partial classes?

Yes you can use partial classes to do somethings you can do with extension methods. In fact this is recommended when you have access to edit the source code. Partial classes allow for a class to be extended over many files then later linked by compiler. However you cannot link partial classes over different assemblies. Partial classess will allow access for private/protected members which is not a luxury of extension methods.

Conclusion:

Extension methods are very useful. However before using them ask the following question, do you really need to use them? Can you get away with other language features. It is not like that they are any bad.