Using GetProperties with BindingFlags.DeclaredOnly in .NET Reflection
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
BindingFlags.DeclaredOnly is useful when reflection should return only the properties introduced on the current type, not the ones inherited from base classes. That sounds simple, but it is easy to forget that DeclaredOnly does not stand alone. You still need to combine it with flags such as Instance, Static, Public, or NonPublic to describe which declared properties you actually want.
What DeclaredOnly Actually Means
When you call GetProperties without DeclaredOnly, reflection can include inherited properties that are visible under the binding rules you specified. Adding DeclaredOnly narrows the result set to members defined directly on the target type.
This is especially useful when:
- comparing a derived type to its base type
- generating metadata only for properties introduced by the current class
- implementing custom mapping or serialization rules for one layer of the hierarchy
A Simple Example
Expected behavior:
- '
allcontainsNameandEmployeeId' - '
declaredcontains onlyEmployeeId'
That is the core behavior of DeclaredOnly.
Why the Other Binding Flags Still Matter
DeclaredOnly does not imply instance-only or public-only behavior. It only filters by where the member was declared. You still need to describe the visibility and member kind you want.
Examples:
- '
BindingFlags.Instance | BindingFlags.Public | BindingFlags.DeclaredOnly' - '
BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.DeclaredOnly'
If you omit Instance and Static, or omit Public and NonPublic, you can easily get an empty result and think reflection is broken.
Declared Properties Versus Hidden Properties
If a derived type hides a base property using new, the new property is declared on the derived type and therefore can appear when using DeclaredOnly.
This returns the derived declaration, not the inherited base property.
A Common Real-World Use Case
Suppose you are building a mapper that should copy only the fields introduced by a derived DTO layer. DeclaredOnly prevents inherited infrastructure properties from polluting the mapping list.
That keeps reflection-based code more intentional, especially in class hierarchies with framework-level base classes.
Performance and Reuse
Reflection is slower than direct property access, so if you use GetProperties repeatedly for the same types, cache the results.
That pattern matters in serializers, mappers, and validation frameworks.
Common Pitfalls
- Assuming
DeclaredOnlyby itself is enough withoutInstance,Static,Public, orNonPublic. - Expecting inherited properties to appear even though
DeclaredOnlyexplicitly filters them out. - Forgetting that a hidden member declared with
newstill counts as declared on the derived type. - Using reflection repeatedly in hot paths without caching.
- Confusing properties with fields, which require
GetFieldsand the corresponding binding flags.
Summary
- '
BindingFlags.DeclaredOnlyreturns only properties introduced on the current type.' - It must be combined with other binding flags that define visibility and member kind.
- It is useful when inherited properties would create noise or incorrect metadata.
- Hidden properties declared in the derived class still count as declared members.
- Cache reflection results if the same lookup happens frequently.

