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?

Community
  • 1
  • 1
Ralph Shillington
  • 20,718
  • 23
  • 91
  • 154

4 Answers4

21

Check its DeclaringType property.

if (methodInfo.DeclaringType == typeof(Foo)) {
   // ...
}
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
  • 2
    This won't work if the inspected method is also an abstract one. Here is the [explanation](https://stackoverflow.com/a/45560768/5259296). – AlexMelw Aug 08 '17 at 08:05
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;
    }
Salvatore Previti
  • 8,956
  • 31
  • 37
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;
    }
}
AlexMelw
  • 2,406
  • 26
  • 35
  • Actually a method **can** reabstract, i.e. be `abstract override`. ([sharplab](https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEDMACFAmDAhaOAYQBtooBYAKAG9qMGtMA3ASwRgFcISsAWDAGUA9mDgBZODAAWwgCYAKAJT1GdKowwBfajqrV0GCMFgIIAYxhZcAJTjHTFmKwB2Ac1LkMIfIU9RKWlUGQwcYM0sMYWZEBFY5OH4hUQkpWUUlAG5dIA===)) – jnm2 Sep 09 '17 at 14:24
  • 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. – jnm2 Sep 09 '17 at 14:26
  • 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()`). – Timo Oct 01 '21 at 08:44
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.

jasonh
  • 29,297
  • 11
  • 59
  • 61