模块类的resolvemethod 在重写的方法上出现混乱
我有一个派生类,其方法覆盖基类的方法,(像这样) 但是 module.ResolveMethod(token, typeArguments, methodArguments) 给了我一个 MethodBase ,其 declaringType 是基本类型,而不是应有的派生类型。
这是 module.ResolveMethod 中的错误吗?
代码发布起来相当复杂,但我使用 Jb Evain 的 MethodBaseRocks
I have a derived class with a method that overrides the base class's method, (like this) but module.ResolveMethod(token, typeArguments, methodArguments)
gives me a MethodBase with a declaringType of the base type, not the derived type like it should be.
Is this a bug in module.ResolveMethod
?
The code is fairly complex to post, but I am using Jb Evain's MethodBaseRocks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不,您正在使用反射/IL 检查。这是静态代码分析。您没有对类型的特定运行时实例执行任何操作。
多态性在运行时“评估”:运行时决定(基于对象的实际类型)调用虚拟方法的哪个版本(基类或派生类)。
您的代码似乎在特定类型上查找方法,根据定义,该方法将返回该类型的方法,因为您正在按原样检查元数据(基类声明基类方法,派生类声明派生方法,没什么花哨的;这只是事实)。
我认为(IIRC)Mono.Cecil(来自 JbEvain)在 MethodDefinition 上公开了 Overloads 集合。我想您可能必须调用 MethodReference.Resolve() 才能获取 MethodDefinition。
如果需要更多背景知识:
没有安全的反射方法可以根据在 CIL 中执行
callvirt
时应用的运行时规则来调用虚拟方法。即即使你这样做:它也会打印
NamespaceName.BaseClass
因为它是声明虚拟的类。No, you are using reflection/IL inspection. This is static code analysis. You are not doing anything on a specific runtime instance of a type.
Polymorphism is 'evaluated' at runtime: the runtime decides (based on the actual type of the object) which version of the virtual method to call (base or derived).
Your code seems to look a method up on a specific type, which will by definition return the method from that type, because you are inspecting the metadata as it is (the base declares the base method, the derived declares the derived method, nothing fancy; it's just the facts).
I think (IIRC) Mono.Cecil (from JbEvain) exposes an Overloads collection on the MethodDefinition. I suppose you may have to call MethodReference.Resolve() in order to get the MethodDefinition.
more background if desired:
There is no safe reflection way to invoke a virtual method according to runtime rules that apply when doing a
callvirt
in CIL. I.e. even if you do:it will print
NamespaceName.BaseClass
because it is the class that declares the virtual.