Type lookupType = typeof (IMenuItem);
IEnumerable<Type> lookupTypes = GetType().Assembly.GetTypes().Where(
t => lookupType.IsAssignableFrom(t) && !t.IsInterface);
5
您可以使用一些LINQ来获取列表:
var types = from type in this.GetType().Assembly.GetTypes()
where type is ISomeInterface
select type;
但真的,那更具可读性吗?
8
我的将在c#3.0 :)
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
基本上,迭代次数最少的是:
loop assemblies
loop types
see if implemented.
55
循环遍历所有已加载的程序集,遍历所有类型,并检查它们是否实现了接口 .
就像是:
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
}
}
}
0
其他答案在这里使用 IsAssignableFrom . 您还可以使用 System 命名空间中的 FindInterfaces ,如here所述 .
static void Main() {
const string qualifiedInterfaceName = "Interfaces.IMyInterface";
var interfaceFilter = new TypeFilter(InterfaceFilter);
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var di = new DirectoryInfo(path);
foreach (var file in di.GetFiles("*.dll")) {
try {
var nextAssembly = Assembly.ReflectionOnlyLoadFrom(file.FullName);
foreach (var type in nextAssembly.GetTypes()) {
var myInterfaces = type.FindInterfaces(interfaceFilter, qualifiedInterfaceName);
if (myInterfaces.Length > 0) {
// This class implements the interface
}
}
} catch (BadImageFormatException) {
// Not a .net assembly - ignore
}
}
}
public static bool InterfaceFilter(Type typeObj, Object criteriaObj) {
return typeObj.ToString() == criteriaObj.ToString();
}
无法激活类型的典型示例是返回的类型是 basebase 但是 base 是在与 derived (调用程序集未引用的程序集)不同的程序集中定义的 .
所以说我们有:
Class A // in AssemblyA
Class B : Class A, IMyInterface // in AssemblyB
Class C // in AssemblyC which references AssemblyB but not AssemblyA
如果 ClassC 在 AssemblyC 中,我们会根据接受的答案做一些事情:
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
12 回答
这对我有用 . 它循环通过类并检查它们是否来自myInterface
做你想做的事情没有简单的方法(就性能而言) .
反射主要用于程序集和类型,因此您必须获取程序集的所有类型并查询它们以获得正确的接口 . 这是一个例子:
这将为您提供在Assembly MyAssembly中实现IMyInterface的所有类型
我在linq代码中有例外,所以我这样做(没有复杂的扩展):
要查找实现IFoo接口的程序集中的所有类型:
请注意,Ryan Rinaldi的建议不正确 . 它将返回0种类型 . 你不能写
因为type是System.Type实例,并且永远不会是IFoo类型 . 而是检查是否可以从类型中分配IFoo . 这将获得您的预期结果 .
此外,Adam Wright的建议,目前被标记为答案,也是不正确的,并且出于同样的原因 . 在运行时,您将看到0种类型返回,因为所有System.Type实例都不是IFoo实现者 .
其他答案没有使用 generic interface .
这个,只需用typeof(T)替换typeof(ISomeInterface) .
所以
我们得到了所有的集会
用于排除接口和抽象接口
将它们列入清单 .
这对我有用(如果你希望你可以在查找中排除系统类型):
您可以使用一些LINQ来获取列表:
但真的,那更具可读性吗?
我的将在c#3.0 :)
基本上,迭代次数最少的是:
循环遍历所有已加载的程序集,遍历所有类型,并检查它们是否实现了接口 .
就像是:
其他答案在这里使用
IsAssignableFrom
. 您还可以使用System
命名空间中的FindInterfaces
,如here所述 .下面是一个示例,它检查当前正在执行的程序集文件夹中的所有程序集,查找实现某个接口的类(为清楚起见,避免使用LINQ) .
如果要匹配多个接口,可以设置接口列表 .
编辑:我刚刚看到编辑,澄清原始问题是减少迭代/代码,这一切都很好,作为一个练习,但在现实世界的情况下,你将需要最快的实现,无论如何底层LINQ看起来有多酷 .
这是我的Utils方法,用于迭代加载的类型 . 它处理常规类和接口,如果您在自己的/第三方代码库中寻找实现,则excludeSystemTypes选项可以大大加快速度 .
我承认,它并不漂亮 .
我很欣赏这是一个非常古老的问题,但我想我会为未来的用户添加另一个答案,因为日期的所有答案都使用某种形式的Assembly.GetTypes .
虽然GetTypes()确实会返回所有类型,但它并不一定意味着你可以激活它们,因此可能会抛出ReflectionTypeLoadException .
无法激活类型的典型示例是返回的类型是
base
base
但是base
是在与derived
(调用程序集未引用的程序集)不同的程序集中定义的 .所以说我们有:
如果
ClassC
在AssemblyC
中,我们会根据接受的答案做一些事情:然后它将抛出一个ReflectionTypeLoadException .
这是因为如果没有
AssemblyC
中对AssemblyA
的引用,您将无法:换句话说
ClassB
是不可加载的,这是对GetTypes的调用检查和抛出的东西 .因此,为了安全地限定可加载类型的结果集,然后根据Phil Haacked文章Get All Types in an Assembly和Jon Skeet code,您将执行以下操作:
然后: