Back to results for “Extension Methods”
C# › Extension Methods

How would you write an extension method on an interface (like IEnumerable<T>) that provides a default implementation shared across EVERY concrete implementing type?

Advanced

Answer

Extension methods on an interface type automatically become available to ALL classes/structs implementing that interface, without those types needing any changes — this is precisely how virtually all of LINQ works, adding dozens of query methods to every IEnumerable<T> implementation across the entire .NET ecosystem, including your own custom collections.
public static class MyLinqExtensions {
  public static T? SecondOrDefault<T>(this IEnumerable<T> source) {
    using var enumerator = source.GetEnumerator();
    if (enumerator.MoveNext() && enumerator.MoveNext()) return enumerator.Current;
    return default;
  }
}

var list = new List<int> { 1, 2, 3 };
int second = list.SecondOrDefault(); // 2 -- works automatically, since List<T> implements IEnumerable<T>
Real-world example Adding a custom LINQ-style query method that automatically works across every existing and future IEnumerable<T> implementation.

Common follow-ups: Why can interfaces' default interface methods (a C# 8+ feature) sometimes achieve a similar goal, and how do they differ from extension methods?