How to tell if MemberInfo represents an override

2019-08-10 11:07发布

问题:

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.

回答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.



回答2:

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.