3 回答
TA贡献1846条经验 获得超7个赞
这是一个普遍的问题,尤其是在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因为如果您尝试实例化接口或抽象类,它将引发异常。
我喜欢强制枚举类实现,IComparable以便可以对它们进行排序。
您的子类必须具有相同的构造函数签名,否则它将引发异常。这通常对我来说不是问题
TA贡献1995条经验 获得超2个赞
假设它们都在同一程序集中定义,则可以执行以下操作:
IEnumerable<AbstractDataExport> exporters = typeof(AbstractDataExport)
.Assembly.GetTypes()
.Where(t => t.IsSubclassOf(typeof(AbstractDataExport)) && !t.IsAbstract)
.Select(t => (AbstractDataExport)Activator.CreateInstance(t));
TA贡献1811条经验 获得超6个赞
typeof(AbstractDataExport).Assembly 告诉您类型所在的程序集(假设所有程序集都在同一位置)。
assembly.GetTypes()为您提供该程序集中的所有类型,或者assembly.GetExportedTypes()为您提供公共类型。
遍历类型并使用type.IsAssignableFrom()会告诉您类型是否派生。
- 3 回答
- 0 关注
- 950 浏览
添加回答
举报