2009-06-11 18 views
12

Estoy tratando de determinar si el objeto MethodInfo que obtengo de una llamada GetMethod en una instancia de tipo se implementa por tipo o por su base.Cómo determinar si MethodInfo reemplaza el método base

Por ejemplo:

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

el método ToString puede ser implementado en la clase Foo o no. Quiero saber si estoy obteniendo la implementación foo?

pregunta relacionada

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

Respuesta

19

comprobar su propiedad DeclaringType.

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

+1 Esa es la única :) –

+0

Esto no funcionará si el método de inspección también es abstracto. Aquí está la [explicación] (https://stackoverflow.com/a/45560768/5259296). –

1

Te recomendamos que consultes la propiedad DeclaringType. Si el método ToString proviene de Foo, entonces DeclaringType será de tipo Foo.

2

¡En lugar de utilizar la reflexión, una forma mucho más rápida es utilizar delegados! Especialmente en la nueva versión del framework, la operación es realmente rápida.

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

Usted tiene que comprobar si DeclaringType propiedad de MemberInfo objeto (DeclaringType hecho, mientras la clase que declara a este miembro) es igual aReflectedType propiedad (que obtiene la clase de objeto que se utilizó para obtener esta instancia de MemberInfo).

Además de eso, también debe verificar la propiedad IsAbstract. Si es true, continuación el método de inspección es definitivamente no invalida, porque "ser abstracto" significa que esta persona es una nueva declaración que no puede tener su aplicación (cuerpo) dentro de la clase actual (pero sólo en clases derivadas en su lugar).

Aquí se muestra un ejemplo del uso del método de extensión se proporciona a continuación:

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

Método de extensión:

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

En realidad, un método ** puede ** reabsorberse, es decir, ser 'anulación abstracta'. ([sharplab] (https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEDMACFAmDAhaOAYQBtooBYAKAG9qMGtMA3ASwRgFcISsAWDAGUA9mDgBZODAAWwgCYAKAJT1GdKowwBfajqrV0GCMFgIIAYxhZcAJTjHTFmKwB2Ac1LkMIfIU9RKWlUGQwcYM0sMYWZEBFY5OH4hUQkpWUUlAG5dIA===)) – jnm2

+0

Tal vez usted está hablando de algo diferente aunque-OP preguntó cómo detectar que un método es una anulación, no la forma de detectar que un método es anulado – jnm2

Cuestiones relacionadas