【问题标题】:Reflection: How to create a precisely filtered list of the Assembly's types?反思:如何创建一个精确过滤的程序集类型列表?
【发布时间】:2026-01-26 01:45:02
【问题描述】:
foreach (var item in Assembly.GetExecutingAssembly().GetTypes()
                             .Where(x => x.BaseType == typeof(Item)))
{
    comboBox1.Items.Add(item);
}
comboBox1.DisplayMember = "Name";

是否可以对其进行修改,以使列表包含从“Item”派生的所有类,即使它们被删除两次或更多次? (即:x.BaseType.BaseType == typeof(Item) 等)

另外,是否可以过滤掉所有的抽象类?

【问题讨论】:

    标签: c# reflection types


    【解决方案1】:

    一个简单的方法是使用IsAssignableFrom

    foreach (var item in Assembly.GetExecutingAssembly().GetTypes()
                                 .Where(x => typeof(Item).IsAssignableFrom(x) && !x.IsAbstract))
    {
        //Handle each item
    }
    

    假设我的“句柄每个项目都是Console.WriteLine(item),我有这样的类结构:

    class ItemBase {}
    class Item : ItemBase {}
    class SuperItem : Item {}
    abstract class SuperSuperItem : SuperItem{}
    class UltimateItem : SuperSuperItem {}
    

    输出将是:

    物品

    超级物品

    终极物品

    请注意,在这种情况下,IsAssignableFrom 自身返回 true,您可以通过将 && x != typeof(Item) 添加到 Where 子句来轻松省略它。

    【讨论】:

      【解决方案2】:

      你可以使用下面的

      public static class Program {
          static void Main(string[] args) {
              var items = Assembly.GetExecutingAssembly().GetTypes()
                                  .Where(x => !x.IsAbstract && x.GetBaseTypes().Contains(typeof(Item)));
          }
      
          public static IEnumerable<Type> GetBaseTypes(this Type type) {
              if (type.BaseType == null) return type.GetInterfaces();
      
              return Enumerable.Repeat(type.BaseType, 1)
                               .Concat(type.GetInterfaces())
                               .Concat(type.GetInterfaces().SelectMany<Type, Type>(GetBaseTypes))
                               .Concat(type.BaseType.GetBaseTypes());
          }
      }
      
      public class Item { }
      public class ItemA : Item { }
      public class ItemB : ItemA { }
      public abstract class ItemC : Item { }
      

      检索基本类型的扩展方法取自Given a C# Type, Get its Base Classes and Implemented Interfaces

      这样做的原因是Type只有BaseType(),我们需要递归地迭代它们以确保我们获得链中其他类的类型。

      程序产生ItemAItemB

      【讨论】: