如何确定显式实现的 MethodInfo 对象引用了哪个接口?
我有一个 MethodInfo
对象,它表示显式实现的接口方法,如下所示。
MethodInfo GetMethod()
{
return typeof(List<>).GetMethod(
"System.Collections.IEnumerable.GetEnumerator",
BindingFlags.Instance | BindingFlags.NonPublic);
}
如何查询此 MethodInfo
对象以获得其实现的接口类型,即表示 System.Collections.IEnumerable
的 Type
对象? InterfaceMapping
结构提供逆操作,获取实现给定接口的类型的 MethodInfo
对象,因此这是行不通的。
请注意,这是一个人为的示例,因为我可以清楚地解析此信息的方法名称。如果可能的话我想避免这样做。
I have a MethodInfo
object that represents an explicitly-implemented interface method, as follows.
MethodInfo GetMethod()
{
return typeof(List<>).GetMethod(
"System.Collections.IEnumerable.GetEnumerator",
BindingFlags.Instance | BindingFlags.NonPublic);
}
How do I query this MethodInfo
object to obtain the interface type it implements, a Type
object representing System.Collections.IEnumerable
? The InterfaceMapping
structure provides the inverse operation, getting the MethodInfo
object of a type that implements a given interface, so that won't work.
Note that this is a contrived example as I can clearly parse the method name for this information. I'd like to avoid doing this if possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我不知道执行此操作的直接方法,但您显然可以反向使用 InterfaceMapping:迭代该方法的声明类型实现的所有接口,检查该方法是否在该接口的接口映射中:
尽管这看起来似乎有点低效,大多数类型实现的接口足够少,所以这不是什么大问题。但欣赏它并不是非常优雅!
I don't know of a direct way of doing this, but you can obviously use InterfaceMapping in reverse: iterate over all interfaces implemented by the method's declaring type, checking if the method is in the interface map for that interface:
Although this may seem a bit inefficient, most types implement few enough interfaces that it shouldn't be a big deal. Appreciate it's not terribly elegant though!
对我的第一个答案感到抱歉,首先我尝试通过
InterfaceMap
结构获取该方法,并且 that 结构中的方法实际上do报告了接口作为DeclaringType
。然后我对它进行了修改,但没有意识到使用您发布的获取MethodInfo
的方法巧妙地破坏了它。不过,好的一面是,这种微妙的差异导致我们认识到接口方法的
MethodInfo
和实现方法的MethodInfo
实际上并不是同一个方法。经过进一步的思考,我实际上非常确定你想做的事情是不可能可靠地完成的。C# 中的显式接口实现是其在 CLR 中实际工作方式的一点语法糖。在其他语言中,单个具体方法可以实现多个接口方法,就像具体类可以实现多个接口类型一样。例如,在 VB.NET 中,这样做是完全合法的:
这里有一个显式实现两个接口方法的方法。如果有可能获得原始接口类 - 甚至原始接口方法 - 您会获得哪一个?你如何解决歧义?
我不是 CLR 内部的专家,但我相信接口映射是单向的。当您隐式或显式实现接口或方法时,编译器会创建一个从接口到实现的映射,这就是它处理针对接口的方法调用所需的全部内容。界面。
认为 C# 生成的方法名称几乎是巧合的。尽管方法名称是 System.Collections.IEnumerable.GetEnumerator,但这实际上只是一个名称,并且实际上没有任何有关编码的 System.Collections.IEnumerable 信息方法本身。
Sorry about my first answer, at first I tried getting to the method through the
InterfaceMap
structure, and the methods in that structure actually do report the interface as theDeclaringType
. Then I tinkered with it and didn't realize it was subtly broken using the method you'd posted to get theMethodInfo
.The upside, though, is that this subtle difference led to the realization that the
MethodInfo
for the interface method, and theMethodInfo
for the implementing method, are not actually the same method. And upon further thought, I am actually pretty sure that what you want to do is impossible to do reliably.Explicit interface implementations in C# are a bit of syntactic sugar over the way it really works in the CLR. In other languages, a single concrete method can implement multiple interface methods the same way a concrete class can implement multiple interface types. For example, in VB.NET, it's perfectly legal to do this:
Here you have one method that's explicitly implementing two interface methods. If it were possible to get the original interface class - or even the original interface method - which one would you get? How do you resolve the ambiguity?
I'm not an expert on the CLR internals, but I believe that interface maps are one-way. When you implement an interface or method, implicitly or explicitly, the compiler creates a map from the interface to the implementation, and that's all it ever needs to handle method calls against the interface.
Think of the C#-generated method names as being almost coincidental. Even though the method name is
System.Collections.IEnumerable.GetEnumerator
, that really is just a name, and there is not actually any information aboutSystem.Collections.IEnumerable
encoded in the method itself.尝试 MethodInfo.DeclaringType 。
Try
MethodInfo.DeclaringType
.