如何找到实现给定接口的所有类?

Posted

技术标签:

【中文标题】如何找到实现给定接口的所有类?【英文标题】:How to find all the classes which implement a given interface? 【发布时间】:2010-10-16 12:54:13 【问题描述】:

在给定的命名空间下,我有一组实现接口的类。我们称之为ISomething。我有另一个类(我们称之为CClass),它知道ISomething,但不知道实现该接口的类。

我希望CClass 查找ISomething 的所有实现,实例化它的一个实例并执行该方法。

有人知道如何使用 C# 3.5 做到这一点吗?

【问题讨论】:

Getting all types that implement an interface with C# 3.0的可能重复 【参考方案1】:

工作代码示例:

var instances = from t in Assembly.GetExecutingAssembly().GetTypes()
                where t.GetInterfaces().Contains(typeof(ISomething))
                         && t.GetConstructor(Type.EmptyTypes) != null
                select Activator.CreateInstance(t) as ISomething;

foreach (var instance in instances)

    instance.Foo(); // where Foo is a method of ISomething

编辑添加了对无参数构造函数的检查,以便对 CreateInstance 的调用成功。

【讨论】:

小小的清理建议——使用 Type.EmptyTypes 而不是实例化一个新的空 Type 数组。 有没有办法在所有加载的程序集中执行此操作? 没关系.. var instances = from assembly in AppDomain.CurrentDomain.GetAssemblies() from t in assembly.GetTypes() where t.GetInterfaces().Contains(typeof(ISomething)) && t.GetConstructor (Type.EmptyTypes) != null select Activator.CreateInstance(t) as ISomething; 不错!自从我开始使用 MEF 以来,我不必尝试这样做。 :) +1:我有一个代码 sn-p,它只使用老式反射,但这要好得多。【参考方案2】:

您可以使用以下方法获取已加载程序集的列表:

Assembly assembly = System.Reflection.AppDomain.CurrentDomain.GetAssemblies()

从那里,您可以获得程序集中的类型列表(假设是公共类型):

Type[] types = assembly.GetExportedTypes();

然后你可以通过在对象上查找该接口来询问每种类型是否支持该接口:

Type interfaceType = type.GetInterface("ISomething");

不确定是否有更有效的反射方式。

【讨论】:

【参考方案3】:

使用 Linq 的示例:

var types =
  myAssembly.GetTypes()
            .Where(m => m.IsClass && m.GetInterface("IMyInterface") != null);

【讨论】:

【参考方案4】:
foreach (Type t in Assembly.GetCallingAssembly().GetTypes())

    if (t.GetInterface("ITheInterface") != null)
    
        ITheInterface executor = Activator.CreateInstance(t) as ITheInterface;
        executor.PerformSomething();
    

【讨论】:

【参考方案5】:

您可以使用以下内容并根据您的需要进行调整。

var _interfaceType = typeof(ISomething);
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly();
var types = GetType().GetNestedTypes();

foreach (var type in types)

    if (_interfaceType.IsAssignableFrom(type) && type.IsPublic && !type.IsInterface)
    
        ISomething something = (ISomething)currentAssembly.CreateInstance(type.FullName, false);
        something.TheMethod();
    

此代码可以使用一些性能增强功能,但这只是一个开始。

【讨论】:

【参考方案6】:

也许我们应该走这条路

foreach ( var instance in Assembly.GetExecutingAssembly().GetTypes().Where(a => a.GetConstructor(Type.EmptyTypes) != null).Select(Activator.CreateInstance).OfType<ISomething>() ) 
   instance.Execute(); 

【讨论】:

以上是关于如何找到实现给定接口的所有类?的主要内容,如果未能解决你的问题,请参考以下文章

如何测试一个类是不是实现了另一个类的所有接口?

获取所有实现给定接口的类

Mybatis Mapper接口是如何找到实现类的-源码分析

如何在 C# 中编写实现给定接口的通用容器类?

接口和内部类

给定一个外壳扩展 CLSID,您如何找到实现 COM 可执行文件或 DLL,并检查其接口和成员?