2009-06-11 16 views
12

Ich versuche festzustellen, ob das MethodInfo-Objekt, das ich von einem GetMethod-Aufruf für eine Typinstanz erhält, vom Typ oder von seiner Basis implementiert wird.So ermitteln Sie, ob MethodInfo eine Überschreibung der Basismethode ist

Zum Beispiel:

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

die ToString-Methode kann in der Foo-Klasse oder nicht implementiert werden. Ich möchte wissen, ob ich die Foo-Implementierung bekomme?

Verwandte Frage

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

Antwort

19

Überprüfen seiner DeclaringType Eigenschaft.

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

+1 Das ist die ein :) –

+0

Dies wird nicht, wenn die inspizierte Methode funktioniert ist auch eine abstrakte. Hier ist die [Erklärung] (https://stackoverflow.com/a/45560768/5259296). –

1

Sie sollten sich die Eigenschaft DeclaringType ansehen. Wenn die ToString-Methode von Foo stammt, wird der DeclaringType vom Typ Foo sein.

2

Anstatt Reflektion zu verwenden, ist es viel schneller, Delegierte zu verwenden! Besonders in der neuen Version des Frameworks ist die Operation sehr schnell.

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

Sie müssen prüfen, ob DeclaringType Eigenschaft MemberInfo Objekt (DeclaringType tatsächlich die Klasse erhält, die dieses Mitglied erklärt) gleichReflectedType Eigenschaft (, die das Klassenobjekt wird, der verwendet wurde, dies zu erhalten Instanz von MemberInfo).

Außerdem müssen Sie auch die Eigenschaft überprüfen IsAbstract. Wenn es true, dann ist die geprüfte Methode ist definitiv nicht außer Kraft gesetzt, weil „abstrakt zu sein“ bedeutet, dass dieses Element eine neue Erklärung, die nicht haben kann es Implementierung ist (Körper) innerhalb aktueller Klasse (aber nur in abgeleitete Klassen). Hier

ist ein Beispiel für die Verwendung der Erweiterungsmethode unten angegeben:

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

Erweiterungsmethode:

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

Eigentlich kann eine Methode ** neu zusammenfassen, d.h. "abstrakte Überschreibung" sein. ([sharplab] (https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4AEDMACFAmDAhaOAYQBtooBYAKAG9qMGtMA3ASwRgFcISsAWDAGUA9mDgBZODAAWwgCYAKAJT1GdKowwBfajqrV0GCMFgIIAYxhZcAJTjHTFmKwB2Ac1LkMIfIU9RKWlUGQwcYM0sMYWZEBFY5OH4hUQkpWUUlAG5dIA===)) – jnm2

+0

Vielleicht fragte etwas, was Sie reden über verschiedene though- OP, wie man erkennen, dass ein Verfahren eine Überschreibung ist, nicht wie zu erkennen dass eine Methode überschrieben wird. – jnm2

Verwandte Themen