views:

45

answers:

2

Let's assume there's a class with a virtual property (let's call it 'P'). It's overridden in a deriving class. Now I want to use something like this: obj.GetType().GetProperty("P") to get info about the overriding property. This search is ambigous, because there are two "P" properties (base and override). So I typed: obj.GetType().GetProperty("P", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance)

It returns the overriding "P" only, but what if I can't guess in compile time if there's an override at all? The latter call would return null. The case is even more complicated, if the hierarchy of inheritance is bigger.

In other words, I want to get the 'top-most' override available, otherwise - the base property. What is the cleanest way to achieve the aim? Only one I know at the moment is to go through all properties and check name and declaring type.

+1  A: 

Have you tried to add BindingFlags.FlattenHierarchy?

M4N
Thank you, this is what I need. The description of FlattenHierarchy on msdn seemed misleading for me, so I didn't take it into account. It says about protected static members, which I don't want to match. Now, after preparing a quick test, I can see BindingFlags.Static | BindingFlags.NonPublic must specified anyway (additionally) to take effect with protected static members.Thanks for pointing out things that should be obvious.
rook
+1  A: 

Basically, I agree with Martin: BindingFlags.FlattenHierarchy is probably what you need. However, I think these are to be used instead of BindingFlags.DeclaredOnly, i.e.

Type type = obj.GetType();
var c = type.GetProperty("P", BindingFlags.FlattenHierarchy | 
                              BindingFlags.Public | 
                              BindingFlags.Instance);

You can then use c.DeclaringType to find out at which level the property was declared.

If you specify DeclaredOnly and the Type type does not declare (but inherit) P, null will be returned.

mnemosyn
Yes, this is what I needed to make things work. The example usage you provided is exactly how it should be done. Thanks!
rook