使用反射通过派生类型在通用基类上调用方法

时间:2018-11-16 14:16:18

标签: c# reflection

我试图通过反射在基类上调用方法,但是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()
    {
        // ...
    }
}

我正在通过反射获取派生类型...

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

myDerivedType中,我期望通过使用以下方法来查看Reset方法:

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

但是publicMethods是空的。

如果我具有派生类型(代表派生类型的System.Type实例),如何获取并调用Reset方法?

2 个答案:

答案 0 :(得分:2)

从msdn中获取有关Type.GetMethods method的信息:

  

您必须指定BindingFlags.Instance或BindingFlags.Static才能获得回报。

更改您对publicMethods = myDerivedType.GetMethods(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance);的呼叫对我来说是有效的。

答案 1 :(得分:2)

这是一个单元测试,它会重复您尝试的场景:

[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,以便知道您要查找实例方法还是静态方法。