I am given:
-
A class “
T” which implements properties that are decorated with Attributes that I am interested in. -
A
PropertyInfo“p” representing a property belonging to (1) an interface “I” thatTimplements, (2) a base class “B” thatTinherits from, or (3) the classTitself.
I need to get the Attributes defined on (or inherited by) the properties in T, even if p‘s DeclaringType is an interface that T implements or a class that T inherits from. So I need a way to get from p to the PropertyInfo that actually exists on T. Thus it seems that there are 3 cases:
-
p.DeclaringType == typeof(T)This is the trivial case. I can iterate through
T‘s properties until I find the match. Example:return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .FirstOrDefault(property => property == p) -
p.DeclaringType == typeof(I)whereIis an interface thatTimplementsThis is more complicated. I found that I can use an InterfaceMapping to find the corresponding implementation of the
pinT. It seems kind of hackish, but here what works:if (p.DeclaringType.IsInterface && typeof(T).GetInterfaces().Contains(p.DeclaringType)) { InterfaceMapping map = typeof(T).GetInterfaceMap(p.DeclaringType); MethodInfo getMethod = p.GetGetMethod(); for (int i = 0; i < map.InterfaceMethods.Length; i++) { if (map.InterfaceMethods[i] == getMethod) { MethodInfo target = map.TargetMethods[i]; return typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) .FirstOrDefault(property => property.GetGetMethod() == target); } } } -
p.DeclaringType == typeof(B)whereBis a class thatTinherits fromI have not yet been able to figure out how to identify the property on
Tthat overrides a virtual propertypdefined inTs base classB.
So my questions are
- In case 3 how do I find the
PropertyInfoonTthat overrides the propertyponB? - Is there a better way to do all three? Perhaps a way to unify the three cases.
I found a way to answer case 3. The key is
MethodInfo.GetBaseDefinitionHowever this only works for properties that have been overridden on
T.Edit:
By comparing the following, it doesn’t matter if the properties have or haven’t been overriden on
T: