Extension methods
Add your own methods to existing types, even ones you can’t change, and understand how LINQ is built from them.
string class or a third-party library. But you can extend them: an extension method is a static method that you call as if it were an instance method of the type.
Writing one
public static class DoubleExtensions // 1. a static class{ // 2. a static method 3. 'this' before the first parameter public static double MmToM(this double mm) => mm / 1000.0; public static bool IsBetween(this double value, double min, double max) => value >= min && value <= max;} double depth = 300;Console.WriteLine(depth.MmToM()); // reads naturallyConsole.WriteLine(4.5.IsBetween(3, 6)); Output
0.3 True
The class must be staticand not nested; the method must bestatic.The first parameter, marked this, is the object the method is “called on”.The namespace containing the class must be imported with usingto see the methods.Extension methods can only use the type’s public members: they don’t break encapsulation.
Extending interfaces
public static class MemberExtensions{ public static double TotalWeight(this IEnumerable<Beam> beams) { double sum = 0; foreach (var b in beams) sum += b.Kg; return sum; }} List<Beam> level1 = LoadLevel(1);Beam[] picked = GetSelection();Console.WriteLine(level1.TotalWeight()); // works on a List…Console.WriteLine(picked.TotalWeight()); // …and an array: both are IEnumerable<Beam>Where, Select, OrderBy and friends are extension methods on IEnumerable<T> in the System.Linq namespace. That is why every collection gets them for free.
Rules of thumb
If a type has an instance method with the same signature, the instance method wins. Use extensions for small, general helpers. Don’t hide important business logic in them. Group them in classes named after what they extend: StringExtensions,GeometryExtensions.
Practice
string Repeat(this string s, int times) and bool IsPalindrome(this string s) (ignore case). Test with "ab".Repeat(3) and "Level".IsPalindrome().
Show the solution
public static class StringExtensions{ public static string Repeat(this string s, int times) => string.Concat(Enumerable.Repeat(s, times)); public static bool IsPalindrome(this string s) { string lower = s.ToLowerInvariant(); for (int i = 0, j = lower.Length - 1; i < j; i++, j--) if (lower[i] != lower[j]) return false; return true; }} Console.WriteLine("ab".Repeat(3));Console.WriteLine("Level".IsPalindrome()); Output
ababab True
Remember
Extension methods are static methods called like instance methods. Declare them in a static class with thison the first parameter.Extending an interface gives the method to every type that implements it. LINQ is a set of extension methods on IEnumerable<T>.