1

Given the following code:

public class Base {
    public virtual void Method() { }
}

public class Derived : Base {
    public override void Method() { }
}

...

var baseMethodInfo = typeof(Base).GetMember("Method")[0];
var derivedMethodInfo = typeof(Derived).GetMember("Method")[0];

Is it possible to determine if the derivedMethodInfo represents a method declaration which overrides another in a base class?

In another question it was observed that had Method been declared abstract (and not implemented) in the base class, derivedMethodInfo.DeclaringType would have turned up as Base, which makes sense after reading @EricLippert's comments. I noticed that in the present example, since the derived class re-declares the method, that derivedMethodInfo.DeclaringType == derivedMethodInfo.ReflectedType, viz. Derived.

There doesn't seem to be any connection between baseMethodInfo and derivedMethodInfo, other than their names are the same and their respective declaring types appear in the same inheritance chain. Is there any better way to make the connection?

The reason I ask is that there appears to be no way to distinguish, through reflection, between the earlier example and the following one:

public class Base {
    public virtual void Method() { }
}

public class Derived : Base {
    public new void Method() { }
}

In this case as well, the Derived class both declares and reflects a member called Method.

Community
  • 1
  • 1
CSJ
  • 3,641
  • 2
  • 19
  • 29
  • 1
    [`GetBaseDefinition()`](http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.getbasedefinition.aspx) should distinguish the two situations, I guess. – Jeppe Stig Nielsen Jul 12 '13 at 20:30
  • @JeppeStigNielsen: Yes; that's a much better answer. – SLaks Jul 12 '13 at 20:40
  • @JeppeStigNielsen: You're absolutely right. I missed it because I was working with MemberInfo instead of MethodInfo. I'll accept this if you make it into an answer! – CSJ Jul 12 '13 at 20:45

2 Answers2

4

A method shadowing a virtual method will have the VtableLayoutMask flag set in Attributes.

Note that an ordinary virtual method (with no similar name from a base type) will also have this flag set.

This flag appears to indicate that the method introduces a new entry in the VTable.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • Was just playing around in LINQPad, and that's indeed the case. +1 well worth it! – Jon Jul 12 '13 at 20:17
  • If I understand your answer, it sounds as though the `VtableLayoutMask` attribute indicates if the method can be overridden, not if it is overriding. In particular, if the new method was declared as `public new virtual void Method()`, then again there would be no way to tell if it shadows the base method or not (here it doesn't). – CSJ Jul 12 '13 at 20:27
  • @CSJ: No. `new virtual` has `VtableLayoutMask` (since it introduces a new Vtable entry); `override` does not. – SLaks Jul 12 '13 at 20:29
  • 1
    @SLaks: Ah, sorry, I misunderstood. I thought that shadowing meant overriding; in fact it means using the `new` keyword. In conclusion I should look for no `VtableLayoutMask` attribute. – CSJ Jul 12 '13 at 20:38
  • @CSJ: And check that it is virtual. – SLaks Jul 12 '13 at 20:39
  • 1
    VtableLayoutMask is not actually a name of an attribute, it is a bit-mask. The debugger isn't smart enough about enums to display good info. The bitmask tests only one bit in the attribute, you really want to look for MethodAttributes.NewSlot. If it is not set then you can assume the default, MethodAttributes.ReuseSlot – Hans Passant May 23 '14 at 09:41
1

There's a more specific class MethodInfo which derives from MemberInfo. Note that not all kinds of members can be virtual (fields cannot, for example).

If you say

var derivedMethodInfo = typeof(Derived).GetMethod("Method");

then you can check if

derivedMethodInfo.GetBaseDefinition() == derivedMethodInfo

or not. See documentation for GetBaseDefinition() where they also have a code example.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181