关于c#:通过反射实现接口

关于c#:通过反射实现接口

Implementations of interface through Reflection

如何通过C#中的反射获取接口的所有实现?


答案是这样;它会搜索整个应用程序域-即您的应用程序当前加载的每个程序集。

1
2
3
4
5
6
7
8
9
10
11
/// <summary>
/// Returns all types in the current AppDomain implementing the interface or inheriting the type.
/// </summary>
public static IEnumerable<Type> TypesImplementingInterface(Type desiredType)
{
    return AppDomain
           .CurrentDomain
           .GetAssemblies()
           .SelectMany(assembly => assembly.GetTypes())
           .Where(type => desiredType.IsAssignableFrom(type));
}

它是这样使用的;

1
var disposableTypes =  TypesImplementingInterface(typeof(IDisposable));

您可能还希望此函数查找实际的具体类型-即过滤掉抽象,接口和通用类型定义。

1
2
3
4
5
6
public static bool IsRealClass(Type testType)
{
    return testType.IsAbstract == false
         && testType.IsGenericTypeDefinition == false
         && testType.IsInterface == false;
}

看看Assembly.GetTypes()方法。它返回可在程序集中找到的所有类型。您要做的就是遍历每个返回的类型,并检查其是否实现了必要的接口。

这样做的一种方法是使用Type.IsAssignableFrom方法。

这是例子。 myInterface是您要搜索的接口。

1
2
3
4
5
6
7
Assembly myAssembly;
Type myInterface;
foreach (Type type in myAssembly.GetTypes())
{
    if (myInterface.IsAssignableFrom(type))
        Console.WriteLine(type.FullName);
}

我确实认为这不是解决问题的有效方法,但是至少,这是一个很好的起点。


1
2
3
4
5
6
7
8
9
10
11
Assembly assembly = Assembly.GetExecutingAssembly();
List<Type> types = assembly.GetTypes();
List<Type> childTypes = new List<Type>();
foreach (Type type in Types) {
  foreach (Type interfaceType in type.GetInterfaces()) {
       if (interfaceType.Equals(typeof([yourinterfacetype)) {
            childTypes.Add(type)
            break;
       }
  }
}

也许像那样...


正如Simon Farrow所建议的,这是一些可能有用的Type扩展方法。这段代码只是对已接受答案的重组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/// <summary>
/// Returns all types in <paramref name="assembliesToSearch"/> that directly or indirectly implement or inherit from the given type.
/// </summary>
public static IEnumerable<Type> GetImplementors(this Type abstractType, params Assembly[] assembliesToSearch)
{
    var typesInAssemblies = assembliesToSearch.SelectMany(assembly => assembly.GetTypes());
    return typesInAssemblies.Where(abstractType.IsAssignableFrom);
}

/// <summary>
/// Returns the results of <see cref="GetImplementors"/> that match <see cref="IsInstantiable"/>.
/// </summary>
public static IEnumerable<Type> GetInstantiableImplementors(this Type abstractType, params Assembly[] assembliesToSearch)
{
    var implementors = abstractType.GetImplementors(assembliesToSearch);
    return implementors.Where(IsInstantiable);
}

/// <summary>
/// Determines whether <paramref name="type"/> is a concrete, non-open-generic type.
/// </summary>
public static bool IsInstantiable(this Type type)
{
    return !(type.IsAbstract || type.IsGenericTypeDefinition || type.IsInterface);
}

例子

要在调用程序集中获取可实例化的实现器:

1
2
var callingAssembly = Assembly.GetCallingAssembly();
var httpModules = typeof(IHttpModule).GetInstantiableImplementors(callingAssembly);

要在当前AppDomain中获取实现者:

1
2
var appDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var httpModules = typeof(IHttpModule).GetImplementors(appDomainAssemblies);

您必须遍历所有感兴趣的程序集。从程序集中,您可以获得其定义的所有类型。请注意,当您执行AppDomain.CurrentDomain.Assemblies时,只会得到已加载的程序集。直到需要时才加载装配件,这意味着您必须在开始搜索之前显式加载装配件。


您是说Type实现的所有接口吗?

像这样:

1
2
3
4
5
6
7
ObjX foo = new ObjX();
Type tFoo = foo.GetType();
Type[] tFooInterfaces = tFoo.GetInterfaces();
foreach(Type tInterface in tFooInterfaces)
{
  // do something with it
}

希望有帮助。


推荐阅读

    linux命令查看接口?

    linux命令查看接口?,系统,设备,地址,网络,信息,电脑,软件,情况,命令,灵活,lin

    linux设备加载命令行?

    linux设备加载命令行?,设备,系统,信息,数字,首页,软件,密码,终端,文件,键盘,L

    linux命令行加载中文?

    linux命令行加载中文?,名称,系统,不了,传播,网上,状态,管理,中文,终端,命令,L

    linux启动加载命令行?

    linux启动加载命令行?,服务,系统,数字,首页,终端,环境,命令,方法,脚本,文件,

    linux加载库的命令?

    linux加载库的命令?,系统,地址,信息,设备,标准,服务,命令,名字,工具,首页,lin

    linux加载驱动命令6?

    linux加载驱动命令6?,信息,名称,设备,系统,电脑,软件,材料,下来,命令,权限,li

    linux加载过滤命令?

    linux加载过滤命令?,数据,系统,工具,标准,官网,灵活,最新,命令,文件,文件名,l

    linux设备加载命令?

    linux设备加载命令?,系统,设备,信息,电脑,第一,命令,文件,分区,磁盘,详细信

    linux网卡加载命令行?

    linux网卡加载命令行?,系统,地址,代码,网络,设备,电脑,名称,网卡,技术指标,

    linux命令刷新加载?

    linux命令刷新加载?,系统,下来,工具,网上,命令,终端,环境变量,以下,文件,路

    linux查看接口命令?

    linux查看接口命令?,地址,系统,标准,命令,管理,工作,文件,端口,目录,路径,lin

    加载linux内核的命令?

    加载linux内核的命令?,系统,信息,地址,电脑,发行,设备,简介,平台,发展,基础,l

    linux加载没有的命令?

    linux加载没有的命令?,系统,服务,工具,信息,设备,标准,工作,命令,检测,代码,

    使用linux命令调接口?

    使用linux命令调接口?,网络,系统,地址,信息,工具,情况,服务,灵活,电脑,名称,

    linux命令添加接口?

    linux命令添加接口?,地址,网络,名称,系统,工具,设备,信息,服务,中心,密码,Lin

    加载变量的linux命令?

    加载变量的linux命令?,工具,系统,名称,环境变量,环境,命令,用户,文件,变量,

    linux模块化加载命令?

    linux模块化加载命令?,软件,系统,设备,代码,信息,环境,适当,资料,网上,电脑,

    linux命令加载模块?

    linux命令加载模块?,设备,系统,工具,检测,信息,模块,内核,文件,命令,杂项,lin

    linux接口模式命令?

    linux接口模式命令?,设备,系统,信息,网络,工具,端口,服务,数字,地址,情况,Lin

    linux命令和应用程序?

    linux命令和应用程序?,软件,系统,环境,管理,基础,情况,位置,电脑,工具,中心,