What is reflection in .NET, and what are its costs?
Quick Answer
Reflection is inspecting and using type metadata at run time — discovering types, properties and attributes, creating instances (Activator.CreateInstance), and invoking members dynamically. It powers serializers, DI containers, ORMs and test runners. It's slower than direct calls, defeats some compiler optimisations, and complicates trimming / Native AOT.
Reflection is reading type metadata at run time — listing a type's properties, checking its attributes, creating an instance without knowing the type at compile time, calling a method by name. It's how serializers, DI containers and ORMs work generically. The downside is speed: a reflective property get or method invoke is far slower than a direct call, so in a hot loop you cache the PropertyInfo or compile it to a delegate once. And it makes trimming and Native AOT harder because the tools can't see which types you'll touch. Increasingly the answer is source generators — System.Text.Json generates the serialization code at build time instead of reflecting at run time.
- Uses:
typeof(T).GetProperties(), reading[Attribute]s, plugin discovery, mapping (AutoMapper), model binding. - Costs: metadata lookups and dynamic invocation are much slower than a direct call; in a hot path this matters.
- Mitigations: cache
PropertyInfo/MethodInfo; compile a delegate once withExpressiontrees orDynamicMethod; or avoid reflection entirely with source generators (System.Text.Json, LoggerMessage, regex) which produce the code at build time. - Reflection over private members needs
BindingFlags.NonPublicand can break with obfuscation or partial trust.