簡體   English   中英

獲取方法的所有派生方法

[英]Get all derived methods of a method

給定C#的方法,我需要在子類中找到所有直接或間接覆蓋該方法的方法。

例如,給定以下類架構

abstract class A { public abstract void m(); }
class B : A { public override void m(){}; }
class C : A { public override void m(){}; }
class D : C { public override void m(){}; }
class E : C { public override void m(){}; }
class F : E { public override void m(){}; }
class G : C {  }
class H : G { public override void m(){}; }

那么, Cm的派生方法將是來自D,E,F,H類的方法。

我想出了以下解決方案,該解決方案似乎可以正常工作,但發現它有些麻煩。 我懷疑有一個聰明的方法可以做到這一點。 任何想法?

    public static IEnumerable<MethodInfo> DerivedMethods(this MethodInfo mi)
    {
        return mi.DeclaringType.Assembly.GetTypes()
            .Where(klass => klass.IsSubclassOf(mi.DeclaringType))
            .Select(subclass => subclass.GetMethods(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
                .SingleOrDefault(m => m.GetBaseDefinition() == mi.GetBaseDefinition()))
            .Where(x => x != null);
    }

使它更緊湊的一種方法是改為使用LINQ關鍵字。

而且SingleOrDefault調用有點多余。 每個類的每個方法最多只能有一個重寫。

另外,我注意到您的代碼僅適用於基 接口的工作方式有些不同,不確定您是否也想實現嗎?

public static IEnumerable<MethodInfo> DerivedMethods(this MethodInfo mi)
{
    Type baseType = mi.DeclaringType;
    IEnumerable<Type> subClasses = baseType.Assembly.GetTypes().Where((klass) => klass != baseType && baseType.IsAssignableFrom(klass));
    if (baseType.IsInterface) {
        return from klass in subClasses
               where !klass.IsInterface
               let map = klass.GetInterfaceMap(baseType)
               select map.TargetMethods[Array.IndexOf(map.InterfaceMethods, mi)];
    }
    else {
        return from klass in subClasses
               where !klass.IsAbstract // include this only if you want instantiable classes
               from m in klass.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
               where m.GetBaseDefinition() == mi.GetBaseDefinition()
               select m;
    }
}

如果你想擴大搜索解決方案中的你會改變所有組件subClasses來:

    IEnumerable<Type> subClasses = from asm in AppDomain.CurrentDomain.GetAssemblies()
                                   from klass in asm.GetTypes()
                                   where klass != baseType && baseType.IsAssignableFrom(klass)
                                   select klass;

暫無
暫無

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

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