Подтвердить что ты не робот

Как определить, является ли MethodInfo переопределением базового метода

Я пытаюсь определить, является ли объект MethodInfo, который я получаю от вызова GetMethod экземпляра типа, реализуется типом или базой.

Например:

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

метод ToString может быть реализован в классе Foo или нет. Я хочу знать, получаю ли я реализацию foo?

Связанный с этим вопрос

Можно ли узнать, переопределен ли виртуальный метод .NET в производном классе?

4b9b3361

Ответ 1

Проверьте его свойство DeclaringType.

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

Ответ 2

Вместо использования рефлексии гораздо более быстрый способ - использовать делегатов! Особенно в новой версии фреймворка операция очень быстрая.

    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

Вам нужно посмотреть свойство DeclaringType. Если метод ToString поступает из Foo, то DeclaringType будет иметь тип Foo.

Ответ 4

Вам нужно проверить, не имеет ли свойство DeclaringType объекта MemberInfo (DeclaringType класс, объявляющий этот элемент) равен ReflectedType свойство (которое получает объект класса который использовался для получения этого экземпляра MemberInfo).

Кроме того, вы также должны проверить свойство IsAbstract. Если - true, , то проверенный метод определенно не переопределен, потому что "быть абстрактным" означает, что этот член является новым объявлением который не может иметь его реализацию (тело) в текущем классе (но только в производных классах).

Ниже приведен пример использования метода расширения, приведенного ниже:

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);
}

Метод расширения:

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;
    }
}