Use Reflection to Invoke an Overridden Base Method

Use reflection to invoke an overridden base method

You can't do that, even with reflection. Polymorphism in C# actually guarantees that Derived.Foo() will always be called, even on an instance of Derived cast back to its base class.

The only way to call Base.Foo() from a Derived instance is to explicitly make it accessible from the Derived class:

class Derived : Base
{
public override void Foo()
{
Console.WriteLine("Derived");
}

public void BaseFoo()
{
base.Foo();
}
}

How can I call a base class's method via reflection?

EDIT: OK, so a bit of clarification; you're not trying to call the base class's implementation from outside either class. Instead, from within the overridden class, you want to reflectively call the parent method's implementation.

... Why? Your object statically knows what it is, and therefore statically knows what its base class is. You can't have two base classes, and you can't dynamically "assign" a base class to a pre-existing child class.

To answer your question, you can't. Any attempt to reflectively call "Foo" using the current instance will infinitely recurse, because the invocation of a MethodInfo makes the method call as if it were coming from outside ('cause it is), and so the runtime will obey inheritance/overriding behaviors. You would have to use the IL hack from the related question.

Invoke an overridden instance method using reflection in java

MethodHandles can be used to invoke a superclass method:

https://www.baeldung.com/java-method-handles

Call method of the derived class through reflection. Possible or no?

The GetType method will give you the real type of Foo at runtime:

public class ClassThatUses
{
public Foo Foo { get; set; }

public void CallPrepare()
{
// Foo.Prepare();
Foo.GetType().GetMethod("Prepare").Invoke(Foo, null);
}
}

Following your edit, if you want to find the runtime type of Foo for a particular instance of ClassThatUses then you'll need to use GetValue to interrogate the value of Foo on that instance:

ClassThatUses o = new ClassThatUses() { Foo = new Bar() };

// Type fooType = o.Foo.GetType();
Type fooType = o.GetType().GetProperty("Foo").GetValue(o, null).GetType();

Detect if a method was overridden using Reflection (C#)

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

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

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

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

How to force inheriting class's method implementation to call base method before invoke own implantation?

I don't think that you can enforce the inheriting classes to always first call a method's super implementation, but:

Normally I use a Template method pattern for cases like this:

public abstract class TemplateEnforcer
{
private void TheSame()
{
Console.WriteLine("Everyone calls me;");
}

public void TemplateMethod()
{
this.TheSame();
this.NeedsImplementation();
}

protected abstract void NeedsImplementation();
}

public class TemplateImplementer : TemplateEnforcer
{
protected override void NeedsImplementation()
{
Console.WriteLine("Implemented in TemplateImplementer");
}
}

Code output for this call new TemplateImplementer().TemplateMethod():

    //Everyone calls me;
//Implemented in TemplateImplementer

Template method pattern benefits:

  1. Implementation of abstract method is forced.
  2. The code is kept DRY.
  3. Bugs are avoided and devs are guided in their development.

Reflection: How to get base method (not original method)?

Walking inheritance tree

You could use some reflection and walk inheritence tree of given type, type by type:

public static Type GetMethodDeclaringTypeClosestInHierarchy(MethodInfo derivedTypeMethod)
{
//Method is not virtual, you have the only definition in inheritance tree
if (!derivedTypeMethod.IsVirtual) return derivedTypeMethod.DeclaringType;

var baseType = derivedTypeMethod.DeclaringType.BaseType;

while (baseType != null)
{
//Check if in base type there is a method
if (baseType.GetMethods().Any(baseTypeMethod =>
//that has same base definition like then one we're checking
baseTypeMethod.GetBaseDefinition() == derivedTypeMethod.GetBaseDefinition()
//and is actually overriden in baseType
&& baseTypeMethod.DeclaringType == baseType))
{

return baseType;
}
//If not, go on higher in inheritance tree
baseType = baseType.BaseType;
}

//Found nothing
return derivedTypeMethod.DeclaringType;
}

Ambiguous method name

Problem with Scott's answer is that when you have two methods with different signatures but same name in inheritance tree:

class A
{
public virtual void Func() { }
public virtual string Func(string test) { return ""; }
}

class B : A
{
public override string Func(string test) => base.Func(test);
public override void Func() => base.Func();
}

class C : B
{
public override void Func() => base.Func();
}

you will get an System.Reflection.AmbiguousMatchException: 'Ambiguous match found.' on

typeof(B).GetMethod("Func",
BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public);

Usage

static void Main(string[] args)
{
var type = typeof(C);

//This will throw with multiple methods of given name:
var method1 = type.GetMethod("Func");

//This will not but you need to be pretty explicit on what you're searching for
var method2 = type.GetMethods().SingleOrDefault(m => m.Name == "Func" && m.ReturnType == typeof(void));

var result = GetMethodDeclaringTypeClosestInHierarchy(method2);
Console.WriteLine(result);

Console.ReadKey();
}


Related Topics



Leave a reply



Submit