代码之家  ›  专栏  ›  技术社区  ›  StriplingWarrior

在C中注册一个类的所有声明的子类#

  •  4
  • StriplingWarrior  · 技术社区  · 16 年前

    在我正在研究的一个概念验证项目中,我有一个通用抽象类,我希望它被一些子类扩展:

    public abstract class Pet {
        public abstract string PetTypeName {get;}
    }
    
    public class Dog : Pet {
        public override string PetTypeName { get { return "Dog"; } }
    }
    

    我想用这个类的所有子类型填充一个静态集合:

    public static List<Type> AllPetTypes = new List<Type> {
        typeof(Dog),
        typeof(Cat),
        //...
    };
    

    但是,当我们想要引入一个新的子类型时,这只增加了一个步骤,而且它很容易出错,因为它只是程序员在运行时可以忘记的一件事情。如何自动创建这样的集合,包括程序集中继承给定父类的每个类型?

    编辑

    作为回答,我会用这个做什么:

    因为我们有多个客户机使用相同的SaaS产品,但通过访问不同的门户“渠道”子集,所以很难跟踪用户如何访问特定页面,以及单击“完成”后应将其发送到何处。

    因此,我正在头脑风暴ASP.NET门户的体系结构可能性,其中每个页面实际上是一个增强的用户控件,它接受一个特定的强类型类来保存其参数,并且跟踪面包屑、创建URL等所涉及的所有任务都被抽象到框架中。因此框架需要了解所有可以像页面一样处理的控件。理想情况下,在框架中创建一个新的用户控件并使其代码隐藏类扩展一个特定的基类就足以将该控件注册为系统中的一个新页面。

    这就引出了我的下一个问题:在给定程序集中查找类型,使用这个问题的建议解决方案中提到的技术,是否可以在ASP.NET Web项目的上下文中工作,在该项目中,类型是在代码后面声明的?我不确定用户控件在什么时候被编译,或者是否被认为是Web项目程序集的一部分。有人有其他见解吗?(我应该把这变成一个新问题吗?)

    3 回复  |  直到 9 年前
        1
  •  13
  •   mqp    16 年前
    var targetAssembly = Assembly.GetExecutingAssembly(); // or whichever
    var subtypes = targetAssembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Pet)));
    
        2
  •  3
  •   jason    16 年前

    你可以从这样的事情开始。这将使所有类型与从定义类型派生的定义类型位于同一程序集中。

    class Aware {
        public static readonly IEnumerable<Type> AllTypes;
        static Aware() {
            Type awareType = typeof(Aware);
            allTypes = Assembly.GetAssembly(awareType)
                               .GetTypes()
                               .Where(t => awareType.IsAssignableFrom(t));        
        }
    }
    

    测试:

    class Foo : Aware { }
    class Bar : Aware { }
    
    foreach (var type in Aware.AllTypes) {
                Console.WriteLine(type);
    }
    

    输出:

    Aware
    Foo
    Bar
    

    我很想知道你会用这个做什么。

        3
  •  0
  •   Sebastian Krysmanski XDS    10 年前
    Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(parentClass)))