Generics sind das Typsystem-Feature von C# (und der CLR), das es erlaubt, Klassen, Strukturen, Schnittstellen, Methoden und Delegates über Typparameter zu definieren. Statt für jeden Element-Typ eine eigene List-, Dictionary- oder Repository-Klasse zu schreiben, wird die Logik einmalig formuliert und vom Compiler bzw. der Runtime für konkrete Typen instanziiert.
Eingesetzt werden Generics flächendeckend in der Standardbibliothek (List, Dictionary, IEnumerable, Task, Span, Memory), in Frameworks (ASP.NET Core IOptions, ILogger, Entity Framework DbSet), in eigenen Geschäftslogiken (Result, Repository) und in Algorithmen (Sortierung, Suche, Caching). Generische Constraints wie where T : class, where T : struct, where T : IComparable oder where T : new() erlauben es, gezielt Annahmen über Typparameter auszudrücken.
Der Einsatzzweck und das gelöste Problem liegen in der Vermeidung von Boxing/Unboxing und im Abbau von Code-Duplikation. Vor Generics arbeiteten C#-1.0-Sammlungen wie ArrayList und Hashtable mit object, was bei Werttypen Boxing erzwang und bei Lesezugriff explizite Casts nötig machte — typunsicher und langsam. Generics sind dagegen monomorphisiert: Pro Werttyp-Instanziierung erzeugt die CLR spezialisierten Maschinencode, ohne Boxing und mit voller Typsicherheit zur Compile-Zeit.
Historisch wurden Generics mit C# 2.0 und CLR 2.0 im Jahr 2005 eingeführt, also drei Jahre nach der ersten C#-Version. Anders als Java, das Generics über ‚Type Erasure' implementierte, hat das CLR-Team Generics als First-Class-Feature der Runtime umgesetzt: Typinformation bleibt zur Laufzeit erhalten, was Reflection, Serialisierung und die Werttyp-Spezialisierung erst möglich macht. Diese Designentscheidung hat den .NET-Stack langfristig stark geprägt und ist eine wesentliche Grundlage für moderne Hochleistungsbibliotheken wie Span, ValueTask und Async-Streams.
Eingeführt wurden Generics von Microsoft Research und der CLR-Architekturgruppe, federführend Don Syme (der später F# konzipierte) und Andrew Kennedy. Don Syme hat die Generics-Implementierung später in mehreren Vorträgen als Sprungbrett für F# beschrieben — viele Konzepte, die F# später als rein funktionale Sprache prägten, wurden zuerst durch die Notwendigkeit, Generics in der CLR sauber zu implementieren, technisch möglich. Damit gelten die .NET-Generics nicht nur als pragmatische Spracherweiterung, sondern als das Fundament, auf dem F# später überhaupt entstehen konnte.