Extension Methods sind ein mit C# 3.0 / .NET 3.5 (2007) eingeführtes Sprachfeature, das es erlaubt, bestehenden Typen — auch solchen aus fremden Bibliotheken oder dem .NET-Framework selbst — neue Methoden hinzuzufügen, ohne den Originalcode zu ändern oder vom Typ abzuleiten. Technisch sind sie statische Methoden in statischen Klassen, deren erster Parameter mit dem Schlüsselwort this markiert ist.
Eingesetzt werden Extension Methods auf vielen Ebenen: als Grundlage von LINQ (Where, Select, OrderBy sind formale Erweiterungsmethoden auf IEnumerable und IQueryable), in Builder-DSLs für ASP.NET Core (services.AddControllers().AddNewtonsoftJson().AddJwtBearer()), in Domain-Bibliotheken (string.IsNullOrWhiteSpace(), IServiceCollection.AddMyDomain()), in Test-Helfern (Should.Be(), Mock.Verify()) und in Formatierungs- und Konvertierungs-Hilfen.
Der Einsatzzweck und das gelöste Problem ergeben sich aus dem Wunsch, fremde Klassen sinnvoll erweitern zu können. Vor Extension Methods waren Helper-Klassen mit statischen Aufrufen wie StringHelper.Truncate(s, 10) üblich, was die Lesbarkeit verschlechterte und in IntelliSense schlecht entdeckbar war. Extension Methods ermöglichen es, solche Methoden als wären sie ‚echte' Member zu schreiben: s.Truncate(10) liest sich natürlich, ist über IntelliSense auffindbar und bleibt klar als Erweiterung markiert (durch using-Direktiven wird die Sichtbarkeit gesteuert).
Historisch wurden Extension Methods als technisches Fundament für LINQ konzipiert. Ohne sie hätten LINQ-Operatoren nicht in fluent-Pipelines kombiniert werden können (sequence.Where(...).Select(...).OrderBy(...)). Spätere Sprachfeatures wie Default Interface Methods (C# 8) und Static Abstract Members in Interfaces (C# 11) ergänzen Extension Methods um zusätzliche Mechanismen zur API-Erweiterung; in Diskussionen werden zudem regelmäßig ‚Extension Properties', ‚Extension Constructors' und ‚Extension Operators' für künftige C#-Versionen erwogen.
Eingeführt wurden Extension Methods vom C#-Sprachteam um Anders Hejlsberg und Mads Torgersen. In den Sprachdesign-Diskussionen wurde lange darüber gerungen, ob this als Kennzeichnung des erweiterten Typs das richtige Schlüsselwort sei oder ob ein neues Wort eingeführt werden sollte. Die Entscheidung für this fiel pragmatisch — es war bereits ein Schlüsselwort, hat semantisch eine klare Verbindung zum ‚Empfänger des Aufrufs' und vermeidet Bruch mit Bestandscode. Das Resultat ist heute eine der charakteristischsten Syntaxen in C# und in fast jeder Codebasis allgegenwärtig.