如何确定显式实现的MethodInfo对象引用哪个接口?

时间:2009-12-26 01:19:08

标签: .net reflection interface methodinfo explicit-interface

我有一个MethodInfo对象,表示一个显式实现的接口方法,如下所示。

MethodInfo GetMethod()
{
    return typeof(List<>).GetMethod(
        "System.Collections.IEnumerable.GetEnumerator",
        BindingFlags.Instance | BindingFlags.NonPublic);
}

如何查询此MethodInfo对象以获取它实现的接口类型,Type对象代表System.Collections.IEnumerableInterfaceMapping结构提供了逆操作,获取了实现给定接口的类型的MethodInfo对象,因此无效。

请注意,这是一个人为的例子,因为我可以清楚地解析此信息的方法名称。如果可能的话,我想避免这样做。

3 个答案:

答案 0 :(得分:4)

我不知道这样做的直接方法,但显然可以反过来使用InterfaceMapping:迭代方法声明类型实现的所有接口,检查该方法是否在该接口的接口映射中: / p>

foreach (Type itf in method.DeclaringType.GetInterfaces())
{
  if (method.DeclaringType.GetInterfaceMap(itf).TargetMethods.Any(m => m == method))
  {
    Console.WriteLine("match: " + itf.Name);
  }
}

虽然这看起来效率有点低,但是大多数类型实现的接口足够少,这应该不是什么大问题。欣赏它并不是非常优雅!

答案 1 :(得分:1)

对我的第一个回答感到抱歉,首先我尝试通过InterfaceMap结构了解该方法,并且 结构实际上执行的方法报告了接口为DeclaringType。然后我修改它并且没有意识到它使用你发布的方法巧妙地破解了MethodInfo

然而,好处是,这种微妙的差异导致认识到接口方法的MethodInfo和实现方法的MethodInfo实际上并不是同一种方法。经过进一步思考,我实在非常确定你想做的事情是不可能做到的。

C#中的显式接口实现与它在CLR中的实际工作方式相比有点语法上的含糊。在其他语言中,单个具体方法可以实现多个接口方法,就像具体类可以实现多个接口类型一样。例如,在VB.NET中,执行此操作是完全合法的:

Public Overrides Function Baz() As String Implements IFoo.Foo, IBar.Bar

这里有一个明确实现两个接口方法的方法。如果有可能获得原始接口类 - 甚至是原始接口方法 - 你会得到哪一个?你如何解决歧义?

我不是CLR内部的专家,但我相信界面地图是单向的。当您实现隐式或显式的接口或方法时,编译器会创建一个映射接口实现,这就是处理针对该实现的方法调用所需的全部内容。接口

将C#生成的方法名称视为几乎巧合。即使方法名称是System.Collections.IEnumerable.GetEnumerator,这实际上只是一个名称,并且实际上没有关于方法本身编码的System.Collections.IEnumerable的任何信息。

答案 2 :(得分:0)

尝试MethodInfo.DeclaringType