Extension methods are methods that can extend existing types without the need to inherit from a class and creating your own custom logic. It can also be applied to interfaces.
Figure 1 From MSDN
Extension methods enable you to “add” methods to existing types without creating a new derived type, recompiling the derived type or otherwise modifying the original type. It means we can extend methods from any type, even types we don't have access to the source code for.
Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.
We build extension methods by declaring it as a static method, but there is a little tweak that makes it compile into a method that can be called from an instance.
Extension methods were born in .NET 3.5 together with LINQ. LINQ was a major feature on the .NET Framework, it introduced several extension methods making data manipulation much easier. Some of the extension methods commonly used are Where, Select and Count.
So how do we create our own extension methods? Simple! We need a couple of things. First we need to create a
static class.
I will provide an example extending strings. Additionally, for simplifying the process to truncate a string, I will create a method.
- namespace Example.Extensions
- {
- public static class StringExtender
- {
- public static string TruncateAt(this string source
- , int maxLength)
- {
- if (source.Length <= maxLength)
- {
- return source;
- }
-
- return source.Substring(0, maxLength);
- }
- }
- }
This simple code will truncate a string. Did you notice something different? Yes, the parameter is declared as this string source. When we create a static class, a static method and use this before the first parameter, we meant to say that it is an extension method.
Now we will try to use it.
- "I will be truncated, lol!".TruncateAt(6);
Wait, are you getting a compilation error? If you are, the reason is simple. We created the extension method using the namespace, for example, Extensions. If we try to use it in another namespace we will need to add the using statement (in Visual Studio 2015 the light-bulb is smart enough to add it for you).
No errors? Did you notice that when we were calling our method we only passed one parameter instead of two? It is because the first one is the instance itself. The parameters passed to this method will be "I will be truncated, lol!" and 6.
Simple, isn't it? Do you want to see some complex examples? What about DistinctBy? It is a method that filters a list leaving only distinct elements comparing by a given expression.
-
-
-
-
-
-
-
-
-
-
- public static IEnumerable<TSource> DistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
- Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer = null)
- {
- if (source == null) throw new ArgumentNullException("source");
- if (keySelector == null) throw new ArgumentNullException("keySelector");
- var keys = new HashSet<TKey>(comparer);
- foreach (var element in source)
- {
- if (keys.Add(keySelector(element)))
- {
- yield return element;
- }
- }
- }
If you are going to manipulate images, you could create a Crop method. And so on, the possibilities are limitless!
That's really cool, isn't it?
Hey, do you know about the morelinq project? The
morelinq project is a collection of extension methods that allows you to do even more with LINQ. They have many pretty useful methods.
And when exactly is the best time to use extension methods and when should we be implementing/extending classes?
Well, at this point you got the general idea on when to use it.