Detect if method has been overridden with Reflection (C #)

Let's say I have a TestBase base class where I define the virtual TestMe () method

class TestBase { public virtual bool TestMe() { } } 

Now I inherit this class:

 class Test1 : TestBase { public override bool TestMe() {} } 

Now, using Reflection, I need to find if the TestMe method has been overridden in a child class - is this possible?

Why do I need this - I am writing a constructor visualizer for the "object" type to show the entire inheritance hierarchy, and also to show which virtual methods were redefined at what level.

+54
override reflection c #
May 28 '10 at 20:47
source share
8 answers

Given the type of Test1 , you can determine if it has its own implementation of TestMe :

 typeof(Test1).GetMethod("TestMe").DeclaringType == typeof(Test1) 

If the declaration came from the base type, this will determine false.

Note that since this is a test declaration and not a true implementation, this will return true if Test1 also abstract and TestMe is abstract, since Test1 will have its own declaration. If you want to rule out this case, add && !GetMethod("TestMe").IsAbstract

+60
May 28 '10 at 20:51
source share

As @CiprianBortos pointed out, the accepted answer is not complete and will lead to an unpleasant error in your code if you use it as is.

His comment provides a magical solution to GetBaseDefinition() , but there is no need to check for DeclaringType if you want to check the common IsOverride tag (which I think was the point of this question), just methodInfo.GetBaseDefinition() != methodInfo .

Or, as an extension method on MethodInfo , I think this will do the trick:

 public static class MethodInfoUtil { public static bool IsOverride(this MethodInfo methodInfo) { return (methodInfo.GetBaseDefinition() != methodInfo); } } 
+21
Apr 04 2018-12-12T00:
source share

I could not get Ken Becket to propose a solution for the job. Here is what I settled on:

  public static bool IsOverride(MethodInfo m) { return m.GetBaseDefinition().DeclaringType != m.DeclaringType; } 

In essence, there are tests.

+18
May 13 '13 at 20:56
source share

A simple solution that will also work for the protected element and properties is as follows:

 var isDerived = typeof(Test1 ).GetMember("TestMe", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly).Length == 0; 

This is the answer of my answer here , which, in turn, made references to this question.

+6
Aug 30 2018-11-11T00:
source share

A method that also works in some non-trivial cases:

 public bool Overrides(MethodInfo baseMethod, Type type) { if(baseMethod==null) throw new ArgumentNullException("baseMethod"); if(type==null) throw new ArgumentNullException("type"); if(!type.IsSubclassOf(baseMethod.ReflectedType)) throw new ArgumentException(string.Format("Type must be subtype of {0}",baseMethod.DeclaringType)); while(type!=baseMethod.ReflectedType) { var methods=type.GetMethods(BindingFlags.Instance| BindingFlags.DeclaredOnly| BindingFlags.Public| BindingFlags.NonPublic); if(methods.Any(m=>m.GetBaseDefinition()==baseMethod)) return true; type=type.BaseType; } return false; } 

And a few ugly tests:

 public bool OverridesObjectEquals(Type type) { var baseMethod=typeof(object).GetMethod("Equals", new Type[]{typeof(object)}); return Overrides(baseMethod,type); } void Main() { (OverridesObjectEquals(typeof(List<int>))==false).Dump(); (OverridesObjectEquals(typeof(string))==true).Dump(); (OverridesObjectEquals(typeof(Hider))==false).Dump(); (OverridesObjectEquals(typeof(HiderOverrider))==false).Dump(); (OverridesObjectEquals(typeof(Overrider))==true).Dump(); (OverridesObjectEquals(typeof(OverriderHider))==true).Dump(); (OverridesObjectEquals(typeof(OverriderNothing))==true).Dump(); } class Hider { public virtual new bool Equals(object o) { throw new NotSupportedException(); } } class HiderOverrider:Hider { public override bool Equals(object o) { throw new NotSupportedException(); } } class Overrider { public override bool Equals(object o) { throw new NotSupportedException(); } } class OverriderHider:Overrider { public new bool Equals(object o) { throw new NotSupportedException(); } } class OverriderNothing:Overrider { } 
+2
Feb 27 2018-12-14T00:
source share

According to this answer, there could also be an easy way to check if the virtual method has been overridden so as not to know the exact derived or base type using the test for MethodAttributes.NewSlot :

 public static bool HasOverride(this MethodInfo method) { return (method.Attributes & MethodAttributes.Virtual) != 0 && (method.Attributes & MethodAttributes.NewSlot) == 0; } 

Together with another extension method

 private const BindingFlags Flags = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance; public static bool HasOverride(this Type type, string name, params Type[] argTypes) { MethodInfo method = type.GetMethod(name, Flags, null, CallingConventions.HasThis, argTypes, new ParameterModifier[0]); return method != null && method.HasOverride(); } 

you can just call

 bool hasOverride = GetType().HasOverride(nameof(MyMethod), typeof(Param1Type), typeof(Param2Type), ...); 

to check if MyMethod is MyMethod in a derived class.

As far as I tested this, it worked fine (on my machine β„’).

+2
May 01, '16 at 22:12
source share
  public static bool HasOverridingMethod(this Type type, MethodInfo baseMethod) { return type.GetOverridingMethod( baseMethod ) != null; } public static MethodInfo GetOverridingMethod(this Type type, MethodInfo baseMethod) { var flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod; return type.GetMethods( flags ).FirstOrDefault( i => baseMethod.IsBaseMethodOf( i ) ); } private static bool IsBaseMethodOf(this MethodInfo baseMethod, MethodInfo method) { return baseMethod.DeclaringType != method.DeclaringType && baseMethod == method.GetBaseDefinition(); } 
+1
May 08 '19 at 11:46
source share

There is a better, safer and faster way to do this. This method makes sense if your instance of the class will have a long life, and the IsOverridden check should be performed several times.

To solve this problem, we can use cache and C # delegates, much faster than reflection!

 // Author: Salvatore Previti - 2011. /// <summary>We need a delegate type to our method to make this technique works.</summary> delegate int MyMethodDelegate(string parameter); /// <summary>An enum used to mark cache status for IsOverridden.</summary> enum OverriddenCacheStatus { Unknown, NotOverridden, Overridden } public class MyClassBase { /// <summary>Cache for IsMyMethodOverridden.</summary> private volatile OverriddenCacheStatus pMyMethodOverridden; public MyClassBase() { // Look mom, no overhead in the constructor! } /// <summary> /// Returns true if method MyMethod is overridden; False if not. /// We have an overhead the first time this function is called, but the /// overhead is a lot less than using reflection alone. After the first time /// this function is called, the operation is really fast! Yeah! /// This technique works better if IsMyMethodOverridden() should /// be called several times on the same object. /// </summary> public bool IsMyMethodOverridden() { OverriddenCacheStatus v = this.pMyMethodOverridden; switch (v) { case OverriddenCacheStatus.NotOverridden: return false; // Value is cached! Faaast! case OverriddenCacheStatus.Overridden: return true; // Value is cached! Faaast! } // We must rebuild cache. // We use a delegate: also if this operation allocates a temporary object // it is a lot faster than using reflection! // Due to "limitations" in C# compiler, we need the type of the delegate! MyMethodDelegate md = this.MyMethod; if (md.Method.DeclaringType == typeof(MyClassBase)) { this.pMyMethodOverridden = OverriddenCacheStatus.NotOverridden; return false; } this.pMyMethodOverridden = OverriddenCacheStatus.Overridden; return true; } /// <summary>Our overridable method. Can be any kind of visibility.</summary> protected virtual int MyMethod(string parameter) { // Default implementation return 1980; } /// <summary>Demo function that calls our method and print some stuff.</summary> public void DemoMethod() { Console.WriteLine(this.GetType().Name + " result:" + this.MyMethod("x") + " overridden:" + this.IsMyMethodOverridden()); } } public class ClassSecond : MyClassBase { } public class COverridden : MyClassBase { protected override int MyMethod(string parameter) { return 2011; } } class Program { static void Main(string[] args) { MyClassBase a = new MyClassBase(); a.DemoMethod(); a = new ClassSecond(); a.DemoMethod(); a = new COverridden(); a.DemoMethod(); Console.ReadLine(); } } 

When you run this program as a console application, it will print:

 MyClassBase result:1980 overridden:False ClassSecond result:1980 overridden:False COverridden result:2011 overridden:True 

Tested with Visual Studio 2010, C # 4.0. It should work on previous versions, but it may be slightly slower in C # less than 3.0 due to optimization for delegates in new releases, tests will be appreciated :) However, it will be even faster than using reflection!

0
Aug 13 2018-11-11T00:
source share



All Articles