使用反射,我如何能得到所有类型的实现接口与c# 3.0/。NET 3.5用最少的代码,最小化迭代?
这是我想重写的内容:
foreach (Type t in this.GetType().Assembly.GetTypes())
if (t is IMyInterface)
; //do stuff
使用反射,我如何能得到所有类型的实现接口与c# 3.0/。NET 3.5用最少的代码,最小化迭代?
这是我想重写的内容:
foreach (Type t in this.GetType().Assembly.GetTypes())
if (t is IMyInterface)
; //do stuff
当前回答
查找程序集中实现IFoo接口的所有类型:
var results = from type in someAssembly.GetTypes()
where typeof(IFoo).IsAssignableFrom(type)
select type;
请注意Ryan Rinaldi的建议是不正确的。它将返回0个类型。你不能写字
where type is IFoo
因为类型是一个系统。类型实例,并且永远不会是IFoo类型。相反,检查IFoo是否可以从类型中赋值。这将得到你预期的结果。
此外,亚当·赖特的建议,目前被标记为答案,也是不正确的,出于同样的原因。在运行时,您将看到返回0类型,因为所有System。类型实例不是IFoo实现者。
其他回答
在选择组装位置时就更好了。如果您知道所有实现的接口都在同一个Assembly.DefinedTypes中,则可以筛选大多数程序集。
// We get the assembly through the base class
var baseAssembly = typeof(baseClass).GetTypeInfo().Assembly;
// we filter the defined classes according to the interfaces they implement
var typeList = baseAssembly.DefinedTypes.Where(type => type.ImplementedInterfaces.Any(inter => inter == typeof(IMyInterface))).ToList();
文/詹·比尔金
我在这里看到了太多过于复杂的答案,人们总是告诉我,我倾向于把事情复杂化。同样使用IsAssignableFrom方法来解决OP问题也是错误的!
下面是我的例子,它从应用程序域中选择所有程序集,然后它采用所有可用类型的平面列表,并检查每个类型的接口列表是否匹配:
public static IEnumerable<Type> GetImplementingTypes(this Type itype)
=> AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes())
.Where(t => t.GetInterfaces().Contains(itype));
查找程序集中实现IFoo接口的所有类型:
var results = from type in someAssembly.GetTypes()
where typeof(IFoo).IsAssignableFrom(type)
select type;
请注意Ryan Rinaldi的建议是不正确的。它将返回0个类型。你不能写字
where type is IFoo
因为类型是一个系统。类型实例,并且永远不会是IFoo类型。相反,检查IFoo是否可以从类型中赋值。这将得到你预期的结果。
此外,亚当·赖特的建议,目前被标记为答案,也是不正确的,出于同样的原因。在运行时,您将看到返回0类型,因为所有System。类型实例不是IFoo实现者。
遍历所有加载的程序集,遍历它们的所有类型,并检查它们是否实现了接口。
喜欢的东西:
Type ti = typeof(IYourInterface);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (Type t in asm.GetTypes()) {
if (ti.IsAssignableFrom(t)) {
// here's your type in t
}
}
}
public IList<T> GetClassByType<T>()
{
return AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.ToList(p => typeof(T)
.IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface)
.SelectList(c => (T)Activator.CreateInstance(c));
}