2009-06-11 3 views
12

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

Например:

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

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

Связанные вопрос

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

ответ

19

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

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

+1 Это одна :) –

+0

Это не будет работать, если проверяемого метода также является абстрактным. Вот [объяснение] (https://stackoverflow.com/a/45560768/5259296). –

1

Вы хотите посмотреть свойство DeclaringType. Если метод ToString поступает из Foo, то DeclaringType будет иметь тип 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; 
    } 
1

Вы должны проверить, если 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; 
    } 
} 
+0

На самом деле метод ** может ** обновить, т. Е. Быть «абстрактным переопределением». ([sharplab] (https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEDMACFAmDAhaOAYQBtooBYAKAG9qMGtMA3ASwRgFcISsAWDAGUA9mDgBZODAAWwgCYAKAJT1GdKowwBfajqrV0GCMFgIIAYxhZcAJTjHTFmKwB2Ac1LkMIfIU9RKWlUGQwcYM0sMYWZEBFY5OH4hUQkpWUUlAG5dIA===)) – jnm2

+0

Может быть, вы говорите о чем-то другом хотя- ОП спросил, как обнаружить, что метод является переопределение, не как обнаружить что метод переопределен. – jnm2