簡體   English   中英

使用反射查找從通用類繼承的類

[英]Find classes which inherits from a generic class using reflection

我需要一種方法來過濾程序集,以獲取從通用類繼承的所有類。 我發現了一些帖子,但它們最像是如何檢查繼承性(例如, 如何檢查一個類是否繼承了另一個類而不實例化它?以及如何檢查一個類是否從通用類派生 )。 但是這些帖子對我沒有幫助。

我所有的類都繼承自一個特定的類,即BaseRepository<T> ,但是有些類可以繼承自InterventionBaseRepository<T> (它也繼承自BaseRepository<T> )。 我需要找到他們。 到目前為止,這是我的代碼:

var q = from t in Assembly.GetExecutingAssembly().GetTypes()
        where t.IsClass && 
             (t.Namespace != null &&
              t.Namespace.StartsWith("AgroWeb.Core.Data.Repository"))
        select t;

因此,簡而言之,上面的查詢按名稱空間獲取了我所有的類,我需要在其中查找那些從InterventionBaseRepository<T>繼承的類。

必須找到的類簽名的示例:

public class CityRepository : InterventionBaseRepository<City>, ICityRepository

以及InterventionBaseRepository聲明:

public class InterventionBaseRepository<T> : BaseRepository<T>
    where T : Entity

我嘗試使用IsAssignableFrom()如上面查詢中鏈接的那些帖子中所述:

t.IsAssignableFrom(typeof(InterventionBaseRepository<Entity>))

這是因為您要檢查的是實體而不是城市。 如果要使用協變泛型參數,請為InterventionBaseRepository指定一個接口,如下所示:

public interface IInterventionBaseRepository<out T> { }

然后讓您的InterventionBaseRepository實現它。 現在,可以將Repo <City>視為Repo <Entity>。

所以:

public class InterventionBaseRepository<T> : BaseRepository<T>, IInterventionBaseRepository<T>
where T : Entity
{
}

這篇文章

            CityRepository value = new CityRepository();
            Type type = value.GetType();
            Type baseType = type.BaseType;
            if (baseType.IsGenericType)
            {
                Console.WriteLine(baseType.Name + " is generic type");

                Type itemType = baseType.GetGenericArguments()[0];
                Console.WriteLine("Generic argument: " + itemType.Name);

                Type genericType = baseType.GetGenericTypeDefinition();
                Console.WriteLine("Generic type: " + genericType.Name);

                Console.WriteLine("Generic base type: " + genericType.BaseType.Name);
            }

            if (type.IsAssignableToGenericType(typeof(BaseRepository<>)))
            {
                Console.WriteLine("IsAssignableToGenericType: BaseRepository<>");
            }

        if (type.IsAssignableToGenericType(typeof(InterventionBaseRepository<>)))
        {
            Console.WriteLine("IsAssignableToGenericType: InterventionBaseRepository<>");
        }

和:

public static class Utils 
{
    public static bool IsAssignableToGenericType(this Type givenType, Type genericType)
    {
        var interfaceTypes = givenType.GetInterfaces();

        foreach (var it in interfaceTypes)
        {
            if (it.IsGenericType && it.GetGenericTypeDefinition() == genericType)
                return true;
        }

        if (givenType.IsGenericType && givenType.GetGenericTypeDefinition() == genericType)
            return true;

        Type baseType = givenType.BaseType;
        if (baseType == null) return false;

        return IsAssignableToGenericType(baseType, genericType);
    }
}

輸出:

InterventionBaseRepository`1 is generic type
Generic argument: City
Generic type: InterventionBaseRepository`1
Generic base type: BaseRepository`1
IsAssignableToGenericType: BaseRepository<>
IsAssignableToGenericType: InterventionBaseRepository<>

暫無
暫無

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

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