我有一个MethodInfo
对象,表示一个显式实现的接口方法,如下所示。
MethodInfo GetMethod()
{
return typeof(List<>).GetMethod(
"System.Collections.IEnumerable.GetEnumerator",
BindingFlags.Instance | BindingFlags.NonPublic);
}
如何查询此MethodInfo
对象以获取它实现的接口类型,Type
对象代表System.Collections.IEnumerable
? InterfaceMapping
结构提供了逆操作,获取了实现给定接口的类型的MethodInfo
对象,因此无效。
请注意,这是一个人为的例子,因为我可以清楚地解析此信息的方法名称。如果可能的话,我想避免这样做。
答案 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
。