this
keyword on the first parameter in a static method in a static class: public float Squared(this float value) { ... }
.FloatExtensions.Squared(number)
) but the real value comes from being able to call it this way: number.Squared()
.Sometimes, you wish a class had a method it doesn’t have. If it is your own, you can usually just add it. If you didn’t make it, you can’t just go add it directly to the class. But that doesn’t mean you’re out of options.
For the sake of picking a sample that is easy to understand but simple, let’s suppose you were very often needing to square and cube float
s.
The code isn’t too bad, and you could always write it out as either of the following options:
float number = 3.0f;
float squared1 = number * number;
float squared2 = Math.Pow(number, 2);
float cubed1 = number * number * number;
float cubed2 = Math.Pow(number, 3);
It’s a single line that isn’t hard to write, but if you’re doing it in lots of places, it might be nice to make a single method for it and reuse it.
The first question to ask when making a method like this is, “Where should this code live?”
Ideally, you’d put it in the float
class.
But you can’t do that.
Another option–one we’ll see the motivation for in a second–is to just make another class for it and make it as a static method there:
static class FloatExtensions
{
public static float Squared(float value)
{
return value * value;
}
public static float Cubed(float value)
{
return value * value * value;
}
}
warning
It is important to point out that the static
keyword has been applied to the class itself, in addition to applying it to each method.
A static class is only allowed to have static members.
In fact, the Console
, Convert
, and Math
class are all static classes.
You can’t create instances of the class at all; you can only call its members using the class name.
In essence, static classes are containers for a set of related static methods, fields, and properties where you wouldn’t or shouldn’t ever create distinct instances of the type.
Which could be used elsewhere in your code like this:
float number = 3.0f;
float squared = FloatExtensions.Squared(number);
float cubed = FloatExtensions.Squared(number);
That works okay, but isn’t easy to understand. It’s more dense and longer than our earlier versions. But just wait…
By adding the this
keyword to the first parameter of a static method, you create an extension method:
static class FloatExtensions
{
public static float Squared(this float value)
{
return value * value;
}
public static float Cubed(this float value)
{
return value * value * value;
}
}
You can still call these methods as FloatExtensions.Squared
and FloatExtensions.Cubed
, but for extension methods, there’s a much better way:
float number = 3.0f;
float squared = number.Squared();
float cubed = number.Cubed();
Instead of listing the first parameter as a parameter, you write it as though the method is an instance method.
This version of the code is far more readable than the previous version, and is arguably even better than even the number * number * number
version.
(The benefits become even clearer if the code to do the task is more complicated than one or two multiplications.)
Use extension methods to augment a class with a method you really need, but where you can’t just add the code to the class because you don’t own it.
tip
The name of the class that extension methods lives in can be whatever you want, as long as it is static.
However, it is a common convention to place them in a class whose name begins with the type that you’re adding extension methods for, and ends with Extensions
.
There are plenty of counterexamples out there, but unless you have a strong reason to want something else, start with this as the default.
warning
The biggest problem with extension methods is that the extension methods may live in a different namespace than the original code.
You will sometimes need to add additional using
directives to your files to get the extension methods to appear, even though the underlying type is already accessible.