C#获取继承某接口或基类的所有子类

曾经有一版的架构设想是根据继承的基类、接口自动实例化相关子类,但考虑到全由架构管理实例化的固定参数、随机顺序等问题,最后推翻了这种做法,但是相关代码却是可以保留下来用于其他需求,大体思路是从程序集获取所有Type,然后遍历查找是否继承于某接口或基类

函数

获取继承接口的所有子类Type

/// <summary>
/// 获取继承接口的所有子类Type
/// </summary>
/// <param name="itype">接口Type</param>
/// <returns></returns>
public static Type[] GetChildClasssInInterface(Type itype)
{
    List<Type> list = new List<Type>();
    var types = Assembly.GetCallingAssembly().GetTypes();   // 获取所有类型
    foreach (var t in types)
    {
        Type[] itypes = t.GetInterfaces();  //获取所有继承接口
        foreach (var it in itypes)
        {
            // 判断是否存在目标接口,存在则加入数组
            if (itype.Equals(it))
            {
                list.Add(t);
            }
        }
    }
    return list.ToArray();
}

获取继承基类的所有子类Type

/// <summary>
/// 获取继承基类的所有子类Type
/// </summary>
/// <param name="btype">基类Type</param>
/// <returns></returns>
public static Type[] GetChildClasssInBaseClass(Type btype)
{
    List<Type> list = new List<Type>();
    var types = Assembly.GetCallingAssembly().GetTypes();   // 获取所有类型
    foreach (var t in types)
    {
        // 不断向上遍历基类,直到基类为空或者查找到符合条件的基类
        Type temp = t;
        while (temp.BaseType != null)
        {
            if (btype.Equals(temp.BaseType))
            {
                list.Add(t);
                break;
            }
            temp = temp.BaseType;
        }
    }
    return list.ToArray();
}

示例

using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
interface IMan
{
    void Say();
}
interface IGirl
{
    void Shopping();
}
public class Animal
{

}
public class Man : Animal, IMan
{
    public void Say()
    {

    }
}
public class Boy : Man
{

}
public class Girl : Man, IGirl
{
    public void Shopping()
    {

    }
}

public class Main : MonoBehaviour
{
    private void Awake()
    {
        Debug.Log("-------- 所有继承 IMan 的子类 --------");
        foreach (var t in GetChildClasssInInterface(typeof(IMan)))
        {
            Debug.Log(t.FullName);
        }
        Debug.Log("-------- 所有继承 IGirl 的子类 --------");
        foreach (var t in GetChildClasssInInterface(typeof(IGirl)))
        {
            Debug.Log(t.FullName);
        }

        Debug.Log("-------- 所有继承 Animal 的子类 --------");
        foreach (var t in GetChildClasssInBaseClass(typeof(Animal)))
        {
            Debug.Log(t.FullName);
        }
        Debug.Log("-------- 所有继承 Man 的子类 --------");
        foreach (var t in GetChildClasssInBaseClass(typeof(Man)))
        {
            Debug.Log(t.FullName);
        }
    }
    /// <summary>
    /// 获取继承接口的所有子类Type
    /// </summary>
    /// <param name="itype">接口Type</param>
    /// <returns></returns>
    public static Type[] GetChildClasssInInterface(Type itype)
    {
        List<Type> list = new List<Type>();
        var types = Assembly.GetCallingAssembly().GetTypes();   // 获取所有类型
        foreach (var t in types)
        {
            Type[] itypes = t.GetInterfaces();  //获取所有继承接口
            foreach (var it in itypes)
            {
                // 判断是否存在目标接口,存在则加入数组
                if (itype.Equals(it))
                {
                    list.Add(t);
                }
            }
        }
        return list.ToArray();
    }
    /// <summary>
    /// 获取继承基类的所有子类Type
    /// </summary>
    /// <param name="btype">基类Type</param>
    /// <returns></returns>
    public static Type[] GetChildClasssInBaseClass(Type btype)
    {
        List<Type> list = new List<Type>();
        var types = Assembly.GetCallingAssembly().GetTypes();   // 获取所有类型
        foreach (var t in types)
        {
            // 不断向上遍历基类,直到基类为空或者查找到符合条件的基类
            Type temp = t;
            while (temp.BaseType != null)
            {
                if (btype.Equals(temp.BaseType))
                {
                    list.Add(t);
                    break;
                }
                temp = temp.BaseType;
            }
        }
        return list.ToArray();
    }
}