Вызвать метод для базового базового класса, используя Reflection через производный тип - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь вызвать метод базового класса с помощью отражения, но GetMethods(...) не находит метод.

Мой базовый класс выглядит так:

public abstract class MyBase<S, T> where S : class, new()
                                   where T : ILocalizableTitle
{
    public IEnumerable<T> For(string systemLangCode)
    {
        // ...
    }

    public IEnumerable<T> For(Person person)
    {
        // ...
    }

    public IEnumerable<T> For(CultureInfo cultureInfo, long tenantId)
    {
        // ...
    }

    public static IEnumerable<Type> GetAllMyTypes()
    {
        var thisType = new StackFrame().GetMethod().DeclaringType;

        return (
                   from t in Assembly.GetExecutingAssembly().GetTypes()
                   where t.IsClass
                         && t.Namespace == thisType?.Namespace
                         && t.BaseType?.Name == thisType?.Name
                   select t).ToList();
    }

    public void Reset()
    {
        // ...
    }
}

Я получаю производный тип через Reflection ...

var myDerivedType = MyBase<object, ILocalizableTitle>.GetAllMyTypes().FirstOrDefault(t => t.Name == forTypeByName);

С myDerivedType Я ожидал увидеть метод Reset, используя следующее:

var publicMethods = myDerivedType.GetMethods(BindingFlags.Public | BindingFlags.FlattenHierarchy)

Но publicMethods пуст.

Как я могу получить и вызвать метод Reset, если у меня есть производный тип, т.е. , экземпляр System.Type, представляющий производный тип?

Ответы [ 2 ]

0 голосов
/ 16 ноября 2018

Вот модульный тест, который повторяет сценарий, который вы пытаетесь:

[TestClass]
public class ReflectionTest
{
    [TestMethod]
    public void ReflectionDiscoversBaseClassMethod()
    {
        var inheritedType = typeof(InheritedClass);
        var inheritedTypeMethods = inheritedType.GetMethods(
            BindingFlags.Public | BindingFlags.FlattenHierarchy);
        Assert.IsTrue(
            inheritedTypeMethods.Any(method => method.Name == "ImplementedMethod"));
    }
}

public abstract class BaseClass
{
    public void ImplementedMethod()
    { }
}

public class InheritedClass : BaseClass { }

Тест не пройден, что подтверждает то, что вы видите.

Я изменил это на:

[TestMethod]
public void ReflectionDiscoversBaseClassMethod()
{
    var inheritedType = typeof(InheritedClass);
    var inheritedTypeMethods = inheritedType.GetMethods(
        BindingFlags.Public | BindingFlags.Instance);
    Assert.IsTrue(inheritedTypeMethods.Any(method => method.Name == "ImplementedMethod"));
}

... и это проходит.

Необходимо указать BindingFlags.Instance, чтобы он знал, ищете ли вы экземпляр или статические методы.

0 голосов
/ 16 ноября 2018

Из сообщения о методе Type.GetMethods :

Вы должны указать BindingFlags.Instance или BindingFlags.Static, чтобы получить возврат.

Изменение вашего звонка на publicMethods = myDerivedType.GetMethods(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance); сработало для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...