How to determine if the MethodInfo is an override

2019-01-27 14:56发布

问题:

I'm trying to determine if the MethodInfo object that I get from a GetMethod call on a type instance is implemented by the type or by it's base.

For example:

Foo foo = new Foo();
MethodInfo methodInfo = foo.GetType().GetMethod("ToString",BindingFlags|Instance);

the ToString method may be implemented in the Foo class or not. I want to know if I'm getting the foo implementation?

Related question

Is it possible to tell if a .NET virtual method has been overriden in a derived class?

回答1:

Check its DeclaringType property.

if (methodInfo.DeclaringType == typeof(Foo)) {
   // ...
}


回答2:

Instead of using reflection a much faster way is to use delegates! Especially in the new version of the framework the operation is really fast.

    public delegate string ToStringDelegate();

    public static bool OverridesToString(object instance)
    {
        if (instance != null)
        {
            ToStringDelegate func = instance.ToString;
            return (func.Method.DeclaringType == instance.GetType());
        }
        return false;
    }


回答3:

You'll want to look at the DeclaringType property. If the ToString method comes from Foo, then the DeclaringType will be of type Foo.



回答4:

You have to check if DeclaringType property of MemberInfo object (DeclaringType actually gets the class that declares this member) is equal to ReflectedType property (which gets the class object that was used to obtain this instance of MemberInfo).

Besides that, you have also to check the property IsAbstract. If it is true, then the inspected method is definitely not overridden, because "being abstract" means that this member is a new declaration that cannot have it's implementation (body) within current class (but only in derived classes instead).

Here is an example of usage of the extension method provided below:

Student student = new Student
{
    FirstName = "Petter",
    LastName = "Parker"
};

bool isOverridden = student.GetType()
    .GetMethod(
        name: nameof(ToString),
        bindingAttr: BindingFlags.Instance | BindingFlags.Public,
        binder: null,
        types: Type.EmptyTypes,
        modifiers: null
    ).IsOverridden(); // ExtMethod

if (isOverridden)
{
    Console.Out.WriteLine(student);
}

Extension Method:

using System.Reflection;

public static class MethodInfoHelper
{
    /// <summary>
    ///     Detects whether the given method is overridden.
    /// </summary>
    /// <param name="methodInfo">The method to inspect.</param>
    /// <returns><see langword="true" /> if method is overridden, otherwise <see langword="false" /></returns>
    public static bool IsOverridden(this MethodInfo methodInfo)
    {
        return methodInfo.DeclaringType == methodInfo.ReflectedType
               && !methodInfo.IsAbstract;
    }
}