Wissen von A bis Z

Reflection

Reflection erlaubt Programmen, in den Spiegel zu schauen und sich selbst bei der Arbeit zuzusehen.

Reflection ist die Fähigkeit von .NET-Programmen, zur Laufzeit Informationen über die eigene Struktur — Assemblies, Typen, Methoden, Felder, Properties, Attribute — zu inspizieren, zu instanziieren und zu manipulieren. Die zentrale API liegt im Namespace System.Reflection und stellt unter anderem die Klassen Assembly, Type, MethodInfo, PropertyInfo, FieldInfo und ConstructorInfo bereit.

Eingesetzt wird Reflection vor allem in Frameworks und Bibliotheken: in Dependency-Injection-Containern, die Konstruktoren analysieren und passende Abhängigkeiten injizieren; in O/R-Mappern wie Entity Framework, die Klassen auf Tabellen abbilden; in Serialisierern wie System.Text.Json oder Newtonsoft.Json; in Test-Frameworks (xUnit, NUnit), die Testmethoden anhand von Attributen finden; in Plugin-Systemen, die Assemblies dynamisch laden; und in Tools wie Mappers, Validators und Code-Generatoren.

Der Einsatzzweck und das gelöste Problem liegen in der Lücke zwischen statischem, kompiliertem Code und dynamischen, datengetriebenen Anforderungen. Anwendungen müssen oft Konfigurationsobjekte aus unbekannten Strukturen erzeugen, polymorph mit unbekannten Typen umgehen oder Verträge dynamisch erfüllen. Reflection liefert dafür ein einheitliches Modell. Der Preis ist Performance: Reflection-Aufrufe sind im Vergleich zu direktem Code spürbar langsamer und schwerer optimierbar; deshalb wird in Hot Paths häufig auf Source Generators, Expression Trees oder vorab generierten Code ausgewichen.

Historisch ist Reflection seit dem .NET Framework 1.0 (2002) Bestandteil der Plattform und über alle CLR-Versionen weitgehend stabil geblieben. Mit dem Aufkommen von Native AOT, Trimming und IL Linker hat Reflection allerdings in den letzten Jahren an Komplexität gewonnen: Dynamisch geladene Typen müssen über Annotationen (DynamicallyAccessedMembers) und Trim-Warnungen explizit dem Linker bekanntgemacht werden, damit sie im finalen Native-Bild nicht weggeschnitten werden.

Eingeführt wurde Reflection in .NET von Microsoft Research; konzeptionell knüpft es an Reflection-Mechanismen aus Smalltalk und Java an. In sehr frühen .NET-Vorträgen (2001/2002) wurde Reflection oft mit dem Versprechen ‚alles, was der Compiler weiß, weiß auch dein Programm zur Laufzeit' beworben — eine Aussage, die in der Praxis zwar weitgehend zutrifft, aber inzwischen durch AOT- und Trimming-Szenarien differenziert betrachtet werden muss. Die Spannung zwischen ‚dynamischem .NET' der Reflection-Tradition und ‚statischem .NET' moderner AOT-Workloads ist eines der prägenden Themen der aktuellen Sprach- und Plattformentwicklung.

Zurück