获取抽象类的所有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。
那么,思考是你的朋友在这里。 在实施之前,您可能需要考虑性能方面 – “反思总是昂贵的”:-)