Extension methods: custom types, value types and using
An extension method can extend any type, including your own (see extension methodsExtension methodsAdd methods to a type you can't change, without touching its source or subclassing it.Opens in a new tab).
Types and interfaces
Extending an interface is more powerful than extending a class: every implementing type gets the method.
static class EnumerableExtensions{ public static bool IsEmpty<T>(this IEnumerable<T> source) => !source.Any();} List<int> list = new List<int>();Console.WriteLine(list.IsEmpty()); // true: works on any IEnumerable<T>The compiler rewrites email.IsValidEmail() into the static call StringExtensions.IsValidEmail(email).
Value types
A struct is copied when passed, so an extension method changes only its copy. this ref Point (C# 7.2) changes the original. A reference type needs no ref (see value types and reference typesValue types and reference typesA value type variable holds the value. A reference type variable holds a reference to an object.Opens in a new tab).
struct Point{ public int X, Y;} static class PointExtensions{ // Looks like it modifies the struct, but it only changes a copy public static void MoveWrong(this Point p) => p.X += 10; public static void MoveRight(this ref Point p) => p.X += 10; // C# 7.2+} // Point pt = new Point { X = 1, Y = 2 };// pt.MoveWrong();// Console.WriteLine(pt.X); // still 1// pt.MoveRight();// Console.WriteLine(pt.X); // 11Namespaces
An extension method is visible only where its namespace is imported, which keeps unrelated extensions from crowding every type. LINQ needs using System.Linq; for this reason. Extension methods cannot reach private members.
namespace MyUtils{ public static class StringExtensions { public static bool IsValidEmail(this string s) => s.Contains("@"); }} // In another file:using MyUtils; // now the compiler can see the extension method string email = "test@test.com";email.IsValidEmail(); // works, and shows up in autocomplete