【问题标题】:Invoke method on generic base class using Reflection via derived type通过派生类型使用反射调用泛型基类上的方法
【发布时间】:2018-11-16 14:16:18
【问题描述】:

我正在尝试通过反射调用基类上的方法,但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 是空的。

如果我有派生类型,我如何获取和调用Reset 方法,即表示派生类型的System.Type 实例?

【问题讨论】:

  • 也许我不明白这个问题。您可以通过调用 来调用派生类型上的Reset() 方法。它是遗传的。
  • 我没有派生类型的实例。我有派生类型
  • 请编辑您的帖子。您的最后一句话是“如果我有一个派生类型的 instance,我如何获取和调用 Reset 方法?”如果您没有对象实例,则不能调用任何成员,除非它是静态的。你能解释一下你在做什么吗?
  • 好的,重点。帖子已被编辑。

标签: c# reflection


【解决方案1】:

来自关于Type.GetMethods method的msdn:

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

将您的电话更改为 publicMethods = myDerivedType.GetMethods(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance); 对我有用。

【讨论】:

    【解决方案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,以便它知道您是在寻找实例方法还是静态方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 2014-03-22
      • 2012-04-25
      • 1970-01-01
      相关资源
      最近更新 更多