使用C#反射查找声明函数的接口

Opt*_*ion 1 c# reflection .net-core

我正在寻找一种简单的方法来获取从类开始的方法的反射信息,并一直返回到声明接口。下面是一段简化的代码:

public interface Ix
{
    void Function();
}
public class X : Ix
{
    public void Function() {}
}

public class Y : X
{
}
Run Code Online (Sandbox Code Playgroud)

类 X 的方法信息没有关于在 Ix 接口中声明的函数的信息。这是电话:

var info = typeof(X).GetMethod("Function");
var baseInfo = info.GetBaseDefinition()
Run Code Online (Sandbox Code Playgroud)

它返回以下数据:

info.DeclaringType --> MyNamespace.X
info.ReflectedType --> MyNamespace.X
baseInfo.DeclaringType --> MyNamespace.X
baseInfo.ReflectedType --> MyNamespace.X
Run Code Online (Sandbox Code Playgroud)

为类 Y 返回相同的信息。

我如何确定这个函数是在接口 Ix 中声明的,而无需遍历所有已实现的接口和类 X 或 Y 的基类?我可能会遗漏一些简单的东西,但我无法弄清楚是什么。这可能是一个错误吗?

这是 .Net Core SDK 版本 2.1.104 和 Visual Studio 2017

Net*_*age 6

这是一个扩展方法,用于检索Type特定MethodInfo在其声明中实现的接口的s Type

首先,一个帮助方法来获取 a 的所有接口映射Type

public static IEnumerable<InterfaceMapping> GetAllInterfaceMaps(this Type aType) =>
    aType.GetTypeInfo()
         .ImplementedInterfaces
         .Select(ii => aType.GetInterfaceMap(ii));
Run Code Online (Sandbox Code Playgroud)

然后,使用帮助器获取单个方法的接口的扩展方法:

public static Type[] GetInterfacesForMethod(this MethodInfo mi) =>
    mi.ReflectedType
      .GetAllInterfaceMaps()
      .Where(im => im.TargetMethods.Any(tm => tm == mi))
      .Select(im => im.InterfaceType)
      .ToArray();
Run Code Online (Sandbox Code Playgroud)

如果你想要一个类的所有方法的接口,你可以使用这个:

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);
Run Code Online (Sandbox Code Playgroud)

要获取与该方法对应的接口声明,您可以使用:

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]));
Run Code Online (Sandbox Code Playgroud)