获取抽象类的所有继承类 [英] Get all inherited classes of an abstract class

查看:60
本文介绍了获取抽象类的所有继承类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个抽象类:

abstract class AbstractDataExport
{
        public string name;
        public abstract bool ExportData();
}

我有从 AbstractDataExport 派生的类:

I have classes which are derived from AbstractDataExport:

class XmlExport : AbstractDataExport
{
    new public string name = "XmlExporter";
    public override bool ExportData()
    {
        ...
    }
}
class CsvExport : AbstractDataExport
{
    new public string name = "CsvExporter";
    public override bool ExportData()
    {
        ...
    }
}

有没有可能做这样的事情?(伪代码:)

Is it possible to do something like this? (Pseudocode:)

foreach (Implementation imp in Reflection.GetInheritedClasses(AbstractDataExport)
{
    AbstractDataExport derivedClass = Implementation.CallConstructor();
    Console.WriteLine(derivedClass.name)
}

具有类似的输出

CsvExporter
XmlExporter

?

这背后的想法是创建一个从 AbstractDataExport 派生的新类,这样我就可以自动遍历所有实现并将名称添加到下拉列表中.只想对派生类进行编码,项目中不做任何改动,重新编译,bingo!

The idea behind this is to just create a new class which is derived from AbstractDataExport so i can iterate through all implementations automatically and add for example the names to a Dropdown-List. I just want to code the derived class without changing anything else in the project, recompile, bingo!

如果您有其他解决方案:告诉他们.

If you have alternative solutions: tell em.

谢谢

推荐答案

这是一个很常见的问题,尤其是在 GUI 应用程序中,我很惊讶没有一个 BCL 类可以开箱即用.这是我的做法.

This is such a common problem, especially in GUI applications, that I'm surprised there isn't a BCL class to do this out of the box. Here's how I do it.

public static class ReflectiveEnumerator
{
    static ReflectiveEnumerator() { }

    public static IEnumerable<T> GetEnumerableOfType<T>(params object[] constructorArgs) where T : class, IComparable<T>
    {
        List<T> objects = new List<T>();
        foreach (Type type in 
            Assembly.GetAssembly(typeof(T)).GetTypes()
            .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T))))
        {
            objects.Add((T)Activator.CreateInstance(type, constructorArgs));
        }
        objects.Sort();
        return objects;
    }
}

一些注意事项:

  • 不要担心此操作的成本" - 您只会执行一次(希望如此),即便如此,它也不会像您想象的那么慢.
  • 您需要使用 Assembly.GetAssembly(typeof(T)),因为您的基类可能位于不同的程序集中.
  • 您需要使用条件 type.IsClass!type.IsAbstract 因为如果您尝试实例化接口或抽象类,它会抛出异常.
  • 我喜欢强制枚举类实现 IComparable 以便它们可以被排序.
  • 您的子类必须具有相同的构造函数签名,否则会引发异常.这对我来说通常不是问题.
  • Don't worry about the "cost" of this operation - you're only going to be doing it once (hopefully) and even then it's not as slow as you'd think.
  • You need to use Assembly.GetAssembly(typeof(T)) because your base class might be in a different assembly.
  • You need to use the criteria type.IsClass and !type.IsAbstract because it'll throw an exception if you try to instantiate an interface or abstract class.
  • I like forcing the enumerated classes to implement IComparable so that they can be sorted.
  • Your child classes must have identical constructor signatures, otherwise it'll throw an exception. This typically isn't a problem for me.

这篇关于获取抽象类的所有继承类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆