获取抽象类的所有inheritance类

我有一个抽象类:

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

我有派生自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() { ... } } 

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

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

与一个输出像

 CsvExporter XmlExporter 

这背后的想法是创build一个派生自AbstractDataExport的新类,这样我就可以自动遍历所有实现,并将名称添加到下拉列表中。 我只想编写派生类而不改变项目中的其他任何东西,重新编译,宾果!

如果您有其他解决scheme:告诉他们。

谢谢

这是一个很常见的问题,特别是在GUI应用程序中,我很惊讶没有BCL类来开箱即可。 这是我怎么做的。

 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因为如果尝试实例化接口或抽象类,它将引发exception。
  • 我喜欢强制枚举类实现IComparable以便他们可以sorting。
  • 你的子类必须有相同的构造函数签名,否则会抛出exception。 这对我来说通常不是问题。

假设它们都是在同一个程序集中定义的,你可以这样做:

 IEnumerable<AbstractDataExport> exporters = typeof(AbstractDataExport) .Assembly.GetTypes() .Where(t => t.IsSubclassOf(typeof(AbstractDataExport)) && !t.IsAbstract) .Select(t => (AbstractDataExport)Activator.CreateInstance(t)); 

它可能不是优雅的方式,但是你可以迭代程序Type.IsSubclassOf(AbstractDataExport)所有类并为每个类调用Type.IsSubclassOf(AbstractDataExport)

typeof(AbstractDataExport).Assembly告诉你一个你的types所在的程序集(假设它们都是相同的)。

assembly.GetTypes()为您提供该程序集或assembly.GetExportedTypes()集中的所有typesassembly.GetExportedTypes()为您提供公共的types。

遍历types并使用type.IsAssignableFrom()会告诉您是否派生types。

那么,思考是你的朋友在这里。 在实施之前,您可能需要考虑性能方面 – “反思总是昂贵的”:-)