We will have to deal with the methods here, and not with the property itself, because these are get / set methods of the property that are actually overridden, and not the properties themselves. I will use the get method since you will never have a property without it, although the complete solution should check for its absence.
Looking at IL, emitted in some cases, the get get method of the base property will have metadata tokens (this is from the C # compiler, others may not allocate hidebysig depending on their method that hides semantics, in which case the method will hide by name):
non-virtual : .method public hidebysig specialname instance virtual : .method public hidebysig specialname newslot virtual instance
The resulting code will have the following tokens:
override : .method public hidebysig specialname virtual instance new : .method public hidebysig specialname instance new virtual : .method public hidebysig specialname newslot virtual instance
Thus, it can be seen from the method’s metadata tokens that it is impossible to determine whether it is new , because the non-virtual base method has the same tokens as the non-virtual new method and the virtual base method has the same tokens as the new virtual method new virtual .
We can say that if a method has a virtual token, but not a newslot token, then it overrides the base method, not its shadows, i.e.
var prop = typeof(ChildClass).GetProperty("TempProperty"); var getMethod = prop.GetGetMethod(); if ((getMethod.Attributes & MethodAttributes.Virtual) != 0 && (getMethod.Attributes & MethodAttributes.NewSlot) == 0) {
Assuming we find that the get method is not an override, we want to know if there is a property in the base class that it obscures. The problem is that, since the method is in another slot in the method table, it actually has no direct relation to the method that it hides. So we’re actually saying, “The base type has some method that meets the criteria for shading,” which depends on whether the hidebysig method or the hidden name.
For the first, we need to check whether the base class has any method that exactly matches the signature, while for the last we need to check whether it has any method with the same name, therefore continuing the code above:
else { if (getMethod.IsHideBySig) { var flags = getMethod.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; flags |= getMethod.IsStatic ? BindingFlags.Static : BindingFlags.Instance; var paramTypes = getMethod.GetParameters().Select(p => p.ParameterType).ToArray(); if (getMethod.DeclaringType.BaseType.GetMethod(getMethod.Name, flags, null, paramTypes, null) != null) {
I think this is a big part of the way, but I still don't think it is right. For starters, I'm not completely familiar with hiding by name, since C # does not support it, and that is almost all that I use, so I may be mistaken in the code here that indicates that the instance method can obscure the static. I also don’t know about the case sensitivity problem (for example, in VB the method called Foo shadow is called the Foo method, if both of them have the same signature and both were hidebysig in C #, the answer is no, but if the answer is yes in VB, this means that the answer to this question is actually non-deterministic).
Well, I'm not sure how much this helps, except to illustrate that it is actually much more complicated than I thought it would be (or I missed something really obvious, in which case I would like to know!). But hopefully he has received enough content to help you achieve what you are trying to do.