1

我有一个派生类,它的方法覆盖基类的方法,(像这样)module.ResolveMethod(token, typeArguments, methodArguments)给了我一个 MethodBase,它的 declaringType 是基类型,而不是应该的派生类型。

这是一个错误module.ResolveMethod吗?

代码发布起来相当复杂,但我使用的是Jb Evain 的 MethodBaseRocks

4

1 回答 1

1

不,您正在使用反射/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,因为它是声明虚拟的类。

于 2011-04-14T20:24:17.960 回答