100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
C#

Extension Methods

Extension methods let you add new callable methods to existing types, including sealed or third-party ones, without modifying their source or subclassing.

LINQ & Functional FeaturesIntermediate7 min readJul 9, 2026
Analogies

Extension Methods

An extension method is a static method that appears to be an instance method on a type it doesn't belong to. Declared in a static class with the first parameter prefixed by the this keyword, extension methods let you 'add' functionality to existing types — including types you don't own, like string, int, or IEnumerable<T> — without editing the original source or requiring inheritance. LINQ itself is implemented almost entirely as a large set of extension methods on IEnumerable<T> and IQueryable<T> in System.Linq, which is why calling .Where() or .Select() on any collection works without those methods existing on the collection class itself.

🏏

Cricket analogy: Adding a custom .StrikeRate() extension method onto an existing BattingStats type, without editing the original class, is like a broadcaster overlaying a new stat on a player's profile without the team having to reissue the scorecard.

Declaring and Using Extension Methods

The static class and method must both be static, and the extended type is marked with this before the first parameter. The calling code doesn't see a static method call syntactically — it looks and reads exactly like an instance method invocation, which is the whole point: extension methods integrate seamlessly into IntelliSense and method-chaining style code. The containing static class's namespace must be brought into scope with a using directive for the extension to be visible at a call site.

🏏

Cricket analogy: Calling player.StrikeRate() and having it read exactly like a built-in property, even though it's really a static helper, is like a commentator referring to a stat so naturally that viewers never notice it isn't part of the original scoreboard software.

csharp
public static class StringExtensions
{
    public static bool IsNullOrBlank(this string? value) =>
        string.IsNullOrWhiteSpace(value);

    public static string Truncate(this string value, int maxLength)
    {
        ArgumentOutOfRangeException.ThrowIfNegative(maxLength);
        return value.Length <= maxLength ? value : value[..maxLength] + "…";
    }
}

public static class EnumerableExtensions
{
    public static IEnumerable<TResult> SelectIndexed<T, TResult>(
        this IEnumerable<T> source, Func<T, int, TResult> selector)
    {
        var index = 0;
        foreach (var item in source)
            yield return selector(item, index++);
    }
}

// Usage reads like built-in instance methods
string? name = null;
Console.WriteLine(name.IsNullOrBlank());          // true, no NullReferenceException

var report = "This description is far too long to display in full".Truncate(20);

var labeled = new[] { "alpha", "beta", "gamma" }
    .SelectIndexed((item, i) => $"{i}: {item}");

Resolution Rules and Limitations

Extension methods are resolved at compile time based on the static type of the expression, not the runtime type — and instance methods always win if a matching one already exists on the type; the extension is only used as a fallback. Extension methods cannot access private members of the type they extend (they aren't truly part of the class), and they cannot override or implement interface members. Because IsNullOrBlank above takes a nullable string?, it can even be called safely on a null reference — extension method invocation does not itself throw NullReferenceException, since it compiles to a plain static method call with the instance passed as an argument.

🏏

Cricket analogy: Calling .Bat() on a Batter falls back to an extension only if no instance method already exists, just as a specialist coaching tip only applies when the player hasn't already been drilled on that exact technique by the team's own coach.

Extension methods are pure syntactic sugar at compile time: name.Truncate(20) compiles to StringExtensions.Truncate(name, 20). This is exactly why you can call an extension method on a null reference without an exception — unlike a genuine instance method call, which requires dereferencing a non-null this.

If a class later adds a real instance method with the same name and signature as an existing extension method, the instance method silently takes precedence at every call site with no compiler warning, which can change behavior across a library upgrade without any visible diff at the call site.

  • Extension methods are static methods with a 'this' modifier on the first parameter, making them callable with instance-method syntax.
  • They let you extend types you don't own — including sealed classes and interfaces — without inheritance.
  • LINQ's Where, Select, and most other query operators are extension methods on IEnumerable<T>/IQueryable<T>.
  • Extension method resolution is based on the compile-time static type, and real instance members always take priority.
  • Extension methods cannot access private members and cannot implement or override interface members.
  • Because they compile to static method calls, they can safely be invoked even on a null reference.

Practice what you learned

Was this page helpful?

Topics covered

#CStudyNotes#Programming#ExtensionMethods#Extension#Methods#Declaring#Resolution#Functions#StudyNotes#SkillVeris