How to determine if the MethodInfo is an override of the base method
Asked Answered
C

4

18

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?

Clepsydra answered 11/6, 2009 at 17:3 Comment(0)
A
21

Check its DeclaringType property.

if (methodInfo.DeclaringType == typeof(Foo)) {
   // ...
}
Aegospotami answered 11/6, 2009 at 17:6 Comment(1)
This won't work if the inspected method is also an abstract one. Here is the explanation.Towbin
M
5

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;
    }
Myrtice answered 13/8, 2011 at 20:20 Comment(1)
Fantastic! I haven't seen this trick anywhere before. How did you come up with it?Swagger
N
1

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

Norland answered 11/6, 2009 at 17:9 Comment(0)
T
1

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;
    }
}
Towbin answered 8/8, 2017 at 6:26 Comment(3)
Actually a method can reabstract, i.e. be abstract override. (sharplab)Perilous
Maybe you're talking about something different though– OP asked how to detect that a method is an override, not how to detect that a method is overridden.Perilous
Regarding abstract methods: Let's say Animal overrides ToString(), and Mammal then has an abstract override of ToString(). In other words, Mammal re-abstracts the method, requiring that its concrete subtypes re-implement it at some point. Would we consider the method to be overridden from the perspective of Mammal? It depends on our definition, of course. One thing we can say for sure is that the method is definitely overridden compared to the original implementation (which happens to be Object.ToString()).Swagger

© 2022 - 2024 — McMap. All rights reserved.