我有一个派生类,它的方法覆盖基类的方法,(像这样) 但module.ResolveMethod(token, typeArguments, methodArguments)
给了我一个 MethodBase,它的 declaringType 是基类型,而不是应该的派生类型。
这是一个错误module.ResolveMethod
吗?
代码发布起来相当复杂,但我使用的是Jb Evain 的 MethodBaseRocks
我有一个派生类,它的方法覆盖基类的方法,(像这样) 但module.ResolveMethod(token, typeArguments, methodArguments)
给了我一个 MethodBase,它的 declaringType 是基类型,而不是应该的派生类型。
这是一个错误module.ResolveMethod
吗?
代码发布起来相当复杂,但我使用的是Jb Evain 的 MethodBaseRocks
不,您正在使用反射/IL 检查。这是静态代码分析。您没有对某个类型的特定运行时实例执行任何操作。
多态性在运行时被“评估”:运行时决定(基于对象的实际类型)调用哪个版本的虚拟方法(基类或派生类)。
您的代码似乎在特定类型上查找方法,根据定义,该方法将返回该类型的方法,因为您正在按原样检查元数据(基声明基方法,派生声明派生方法,没什么特别的; 这只是事实)。
我认为(IIRC)Mono.Cecil(来自 JbEvain)在 MethodDefinition 上公开了一个重载集合。我想您可能必须调用 MethodReference.Resolve() 才能获得 MethodDefinition。
如果需要更多背景:
callvirt
根据在 CIL 中执行时应用的运行时规则,没有安全的反射方式来调用虚拟方法。即即使你这样做:
class BaseClass
{ public virtual void SomeMethod() {} }
class Derived :BaseClass {}
class MainClass
{
public static void Main (string[] args)
{
Expression<Action<Derived>> expr = (instance) => instance.SomeMethod();
var method = (expr.Body as MethodCallExpression).Method;
Console.WriteLine(method.DeclaringType);
}
}
它将打印NamespaceName.BaseClass
,因为它是声明虚拟的类。