【问题标题】:Discovering derived types using reflection使用反射发现派生类型
【发布时间】:2010-03-02 10:57:01
【问题描述】:

使用反射,是否可以发现从给定类型派生的所有类型?

大概范围将限制在单个程序集中。

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    几乎和达林的一样,但是给你..

        public static List<Type> FindAllDerivedTypes<T>()
        {
            return FindAllDerivedTypes<T>(Assembly.GetAssembly(typeof(T)));
        }
    
        public static List<Type> FindAllDerivedTypes<T>(Assembly assembly)
        {
            var derivedType = typeof(T);
            return assembly
                .GetTypes()
                .Where(t =>
                    t != derivedType &&
                    derivedType.IsAssignableFrom(t)
                    ).ToList();
    
        } 
    

    类似:

    var output = FindAllDerivedTypes<System.IO.Stream>();
                foreach (var type in output)
                {
                    Console.WriteLine(type.Name);
                }
    

    输出:

    NullStream
    SyncStream
    __ConsoleStream
    BufferedStream
    FileStream
    MemoryStream
    UnmanagedMemoryStream
    PinnedBufferMemoryStream
    UnmanagedMemoryStreamWrapper
    IsolatedStorageFileStream
    CryptoStream
    TailStream
    

    【讨论】:

    • 我假设您使用IsAssignableFrom 而不是IsSubclassOf 来说明接口。但是在接口上调用它也会返回它的实现类。
    【解决方案2】:
    var derivedTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                       where t.IsSubclassOf(typeof(A))
                       select t;
    

    【讨论】:

    • 值得一提的是,这个查询只检索直接派生自A类型的接口或类。
    • @ZenLulz IsSubclassOf method 名称具有误导性。实际上,它为派生类返回true
    【解决方案3】:
    var types = Assembly
        .GetExecutingAssembly()
        .GetTypes()
        .Where(t => typeof(SomeBaseType).IsAssignableFrom(t) && 
                    t != typeof(SomeBaseType))
        .ToArray();
    

    【讨论】:

      【解决方案4】:

      我将@Hath 的优秀答案重写为扩展方法:

      public static class TypeExtensions
      {
          public static List<Type> GetAllDerivedTypes(this Type type)
          {
              return Assembly.GetAssembly(type).GetAllDerivedTypes(type);
          }
      
          public static List<Type> GetAllDerivedTypes(this Assembly assembly, Type type)
          {
              return assembly
                  .GetTypes()
                  .Where(t => t != type && type.IsAssignableFrom(t))
                  .ToList();
          }
      }
      

      用法:

      var listOfDerived = typeof(MyClass).GetAllDerivedTypes();
      

      【讨论】:

      • 为什么使用IsAssignableFrom 而不是IsSubclassOf?也许你想支持接口?但该结果将包括实现类。
      • @HappyNomad 你说得很好。就我而言,我想支持接口。
      • 我的answer 重复问题支持接口。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-22
      • 2021-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多