簡體   English   中英

使用反射通過派生類型在通用基類上調用方法

[英]Invoke method on generic base class using Reflection via derived type

我試圖通過反射在基類上調用方法,但是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方法?

從有關Type.GetMethods方法的msdn中:

您必須指定BindingFlags.Instance或BindingFlags.Static才能獲得回報。

將您的調用更改為publicMethods = myDerivedType.GetMethods(BindingFlags.Public | BindingFlags.FlattenHierarchy | BindingFlags.Instance); 為我工作。

這是一個單元測試,它會重復您嘗試的方案:

[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這樣它才能知道您要查找實例還是靜態方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM