Как определить, является ли MethodInfo переопределением базового метода - PullRequest
12 голосов
/ 11 июня 2009

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

Например:

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

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

Смежный вопрос

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

Ответы [ 4 ]

20 голосов
/ 11 июня 2009

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

if (methodInfo.DeclaringType == typeof(Foo)) {
   // ...
}
2 голосов
/ 14 августа 2011

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

    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;
    }
1 голос
/ 08 августа 2017

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

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

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

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;
    }
}
1 голос
/ 11 июня 2009

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

...