Метод разрешения класса модуля портит переопределенные методы - PullRequest
1 голос
/ 14 апреля 2011

У меня есть производный класс с методом, который переопределяет метод базового класса, (например) , но module.ResolveMethod(token, typeArguments, methodArguments) дает мне MethodBase с declaringType базового типа, а не производного типа, подобного этому. должно быть.

Это ошибка в module.ResolveMethod?

Код довольно сложен для публикации, но я использую JB Evain's MethodBaseRocks

1 Ответ

1 голос
/ 15 апреля 2011

Нет, вы используете проверку отражения / IL.Это статический анализ кода.Вы ничего не делаете с конкретным экземпляром среды выполнения типа.

Полиморфизм «оценивается» во время выполнения: среда выполнения решает (на основе фактического типа объекта), какую версию виртуального метода вызывать (базовый или производный).

Ваш код, похоже, ищет метод определенного типа, который по определению возвращает метод этого типа, поскольку вы проверяете метаданные такими, какие они есть (база объявляет базуmethod, производный объявляет производный метод, ничего сложного, это просто факты).

Я думаю (IIRC) Mono.Cecil (из JbEvain) предоставляет коллекцию Overloads для 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, потому что это класс, который объявляет виртуальный.

...