1

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

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

如何查询此MethodInfo对象以获取它实现的接口类型,一个Type对象表示System.Collections.IEnumerable?该InterfaceMapping结构提供了逆操作,获取MethodInfo实现给定接口的类型的对象,因此这不起作用。

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

4

3 回答 3

4

我不知道这样做的直接方法,但是您显然可以反向使用 InterfaceMapping:遍历由方法的声明类型实现的所有接口,检查该方法是否在该接口的接口映射中:

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

尽管这可能看起来有点低效,但大多数类型实现的接口数量很少,这应该没什么大不了的。欣赏它虽然不是非常优雅!

于 2009-12-26T02:04:40.127 回答
1

抱歉我的第一个答案,起初我尝试通过InterfaceMap结构获取方法,并且该结构中的方法实际上确实接口报告为DeclaringType. 然后我对其进行了修补,并没有意识到使用您发布的获取MethodInfo.

不过,好处是,这种细微的差异导致人们意识到MethodInfofor 接口方法和MethodInfofor 实现方法实际上不是同一个方法。经过进一步思考,我实际上很确定您想要做的事情不可能可靠地完成。

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

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

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

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

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

于 2009-12-26T02:14:36.303 回答
0

试试MethodInfo.DeclaringType

于 2009-12-26T01:27:41.417 回答