I am looking for an easy way to get the reflection information on the method starting all the way from the class, and going back all the way to the declaring interface. Here is the simplified piece of code:
public interface Ix
{
void Function();
}
public class X : Ix
{
public void Function() {}
}
public class Y : X
{
}
Method info for class X has no information about Function being declared in Ix interface. Here is the call:
var info = typeof(X).GetMethod("Function");
var baseInfo = info.GetBaseDefinition()
It returns the following data:
info.DeclaringType --> MyNamespace.X
info.ReflectedType --> MyNamespace.X
baseInfo.DeclaringType --> MyNamespace.X
baseInfo.ReflectedType --> MyNamespace.X
The same information is returned for class Y.
How can I figure out that this Function was declared in interface Ix without going through all implemented interfaces and base classes of class X or Y? I could be missing something simple but I cannot figure out what. Could this be a bug?
This is .Net Core SDK version 2.1.104 and Visual Studio 2017
Here is an extension method to retrieve the Types of the interfaces that a particular MethodInfo implements in its declaring Type:
First, a helper method to get all the interface maps for a Type:
public static IEnumerable<InterfaceMapping> GetAllInterfaceMaps(this Type aType) =>
aType.GetTypeInfo()
.ImplementedInterfaces
.Select(ii => aType.GetInterfaceMap(ii));
Then, an extension method that uses the helper to get the interfaces for a single method:
public static Type[] GetInterfacesForMethod(this MethodInfo mi) =>
mi.ReflectedType
.GetAllInterfaceMaps()
.Where(im => im.TargetMethods.Any(tm => tm == mi))
.Select(im => im.InterfaceType)
.ToArray();
If you wanted the interfaces for all the methods of a class, you can use this instead:
public static ILookup<MethodInfo, Type> GetMethodsForInterfaces(this Type aType) =>
aType.GetAllInterfaceMaps()
.SelectMany(im => im.TargetMethods.Select(tm => new { im.TargetType, im.InterfaceType, tm }))
.ToLookup(imtm => imtm.tm, imtm => imtm.InterfaceType);
To get the interface declarations that correspond to the method, you can use this:
public static IEnumerable<MethodInfo> GetInterfaceDeclarationsForMethod(this MethodInfo mi) =>
mi.ReflectedType
.GetAllInterfaceMaps()
.SelectMany(map => Enumerable.Range(0, map.TargetMethods.Length)
.Where(n => map.TargetMethods[n] == mi)
.Select(n => map.InterfaceMethods[n]));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With