2

I want to be able to use reflection to tell that an implementation of the method GetName in SomClassImpl comes from the interface IHasName. As an example:

public interface IHasName
{
    string GetName();
}

public interface IOtherInterface
{
    //...elided...
}

public class MyClass : IHasName, IOtherInterface
{
    /*
     * I want to use reflection to know this 
     * implements IHasName.GetName()
     */
    public string GetName()
    {
        return "me";
    }
}

Is this possible?

When I tried typeof(MyClass).GetMethod("GetName").GetBaseDefinition().DeclaringType and typeof(MyClass).GetMethod("GetName").DeclaringType, they both return the implementing class, not the interface.

Don Rhummy
  • 24,730
  • 42
  • 175
  • 330
  • 1
    Unless `MyClass` is abstract, isn't it *required* to implement `GetName`? When would there be a case that it isn't implemented but still implements the interface? I understand that new C# versions have interface implementations, but I think this is syntactic sugar for inserting the implementation into the derived class... – Ron Beyer May 08 '19 at 20:13
  • @RonBeyer I think I was unclear, sorry. I don't need to know it implemented interface "X". I want to know instead, "this method is from interface X, and this one is from interface Y, and this one is from the impending class only" – Don Rhummy May 08 '19 at 20:25
  • 1
    https://stackoverflow.com/questions/1113635/how-to-get-methodinfo-of-interface-method-having-implementing-methodinfo-of-cla is probably what you are looking for... Note that same method can be implementing multiple interfaces and be careful with multiple methods with the same name – Alexei Levenkov May 08 '19 at 20:31
  • `var iFC = myClass.GetType().GetInterfaces().FirstOrDefault(ifc => ifc.GetMethods().Any(m => m.Name.Equals("[MethodName]")));`. Or with a value found with `myClass.GetType().GetMethods()`. – Jimi May 08 '19 at 20:54
  • @AlexeiLevenkov The link you posted is exactly the code I tried that did *not* work – Don Rhummy May 08 '19 at 21:11
  • 1
    @DonRhummy you may want to [edit] post to explain how/why GetInterfaceMap did not work... – Alexei Levenkov May 08 '19 at 21:34

2 Answers2

2

I see two possibilities your scenario to happen:

  1. Class implements the interface
  2. Class inherits a class which implements the interface

In the former case, typeof(Foo).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindiFoongFlags.DeclaredOnly) returns the method info.

In the latter case, typeof(Bar).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly) returns null.

See an example here.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
1

The following will tell if the object implements the interface:

unkObj is IHasName

This will too if using reflection on a type instead of an object:

typeof(IHasName).IsAssignableFrom(typeof(MyClass))

This will get the method associated with the interface, and invoking it with any type that implements the interface with call the associated method in its class:

MethodInfo methodIHasName = typeof(IHasName).GetMethod("GetName", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
string name = methodIHasName.Invoke(unkObj, new object[0]);

If you absolutely need to get the MethodInfo of MyClass and all you have is the MethodInfo of the interface IHasName, you can map the interface as follows: (Thanks @Alexei Levenkov for the link)

var map = typeof(MyClass).GetInterfaceMap(methodIHasName.DeclaringType);
var index = Array.IndexOf(map.InterfaceMethods, methodIHasName);
return map.TargetMethods[index];
Rhaokiel
  • 813
  • 6
  • 17
  • 1
    this is the right answer as the other one assumes that interface methods are implemented with the same name, but does not take into account explicit implementation. – Yennefer Jun 05 '19 at 13:05