3

How can I use reflection to determine what method will be called given a Type that implements (or inherits an implementation of) an interface and a MethodInfo of the method from that interface?

Consider the following classes:

using System;

public class A : IDisposable {
    public virtual void Dispose() { Console.WriteLine("A.Dispose"); }
}

public class B : A {
    public new virtual void Dispose() { Console.WriteLine("B.Dispose"); }
}

public class C : A, IDisposable {
    public new virtual void Dispose() { Console.WriteLine("C.Dispose"); }
}

public class D : A, IDisposable {
    void IDisposable.Dispose() { Console.WriteLine("D.IDisposable.Dispose"); }
}

public class Program
{
    public static void Main()
    {
        ((IDisposable)new A()).Dispose(); // A.Dispose
        ((IDisposable)new B()).Dispose(); // A.Dispose
        ((IDisposable)new C()).Dispose(); // C.Dispose
        ((IDisposable)new D()).Dispose(); // D.IDisposable.Dispose
    }
}

I suppose I could do a brute-force search for the most derived method

  • with the same signature
  • and with either the name or qualified name of the interface method
  • and ignore newslot methods in classes that inherit (rather than implement) the interface
  • and ignore any overrides of ignored methods
  • and ...

It gets to be a complex list of corner cases which will be hard to get right, not to mention that it would miss overrides with unrelated names which can be created using TypeBuilder.DefineMethodOverride.

Is there a better way to do this?

Carl Reinke
  • 345
  • 2
  • 12
  • Why do you need to? It seems like you're trying to replicate the compiler's overload resolution logic. – D Stanley May 12 '16 at 02:41
  • I am using `Reflection.Emit` to define a type that implements an interface and also derives from a type that implements the same interface. I want my implementation of that interface to call the implementation of the interface in the base type. I cannot use `OpCodes.Callvirt` because that will just call the method in my type. I do not want to call a method that looks like – but does not actually implement – the interface method. – Carl Reinke May 12 '16 at 02:47
  • Please specify the 4 scenarios in your code, A/B/C/D which one is your expected and which isn't. – Cheng Chen May 12 '16 at 02:57
  • For each class A/B/C/D, the desired method to be found using reflection is the one shown in the comment. For any given class, the desired method is the one that will be called when the interface method is called. – Carl Reinke May 12 '16 at 02:59
  • Linked as duplicate question gives you `Type.GetInterfaceMap` answer to your exact question. Note that if you are implementing some sort of interface proxy for interception purposes it is better to contain actual implementation rather than inherit, especially if you expect some types outside of your control that may not have a way to construct them. – Alexei Levenkov May 12 '16 at 03:22

0 Answers0