C# 通过反射实现接口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/80247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 11:18:07  来源:igfitidea点击:

Implementations of interface through Reflection

提问by

How can I get all implementations of an interface through reflection in C#?

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

回答by Alex Duggleby

Do you mean all interfaces a Type implements?

你的意思是 Type 实现的所有接口?

Like this:

像这样:

ObjX foo = new ObjX();
Type tFoo = foo.GetType();
Type[] tFooInterfaces = tFoo.GetInterfaces();
foreach(Type tInterface in tFooInterfaces)
{
  // do something with it
}

Hope tha helpts.

希望有帮助。

回答by Anton

Have a look at Assembly.GetTypes()method. It returns all the types that can be found in an assembly. All you have to do is to iterate through every returned type and check if it implements necessary interface.

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

On of the way to do so is using Type.IsAssignableFrommethod.

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

Here is the example. myInterfaceis the interface, implementations of which you are searching for.

这是示例。myInterface是接口,您正在搜索的实现。

Assembly myAssembly;
Type myInterface;
foreach (Type type in myAssembly.GetTypes())
{
    if (myInterface.IsAssignableFrom(type))
        Console.WriteLine(type.FullName);
}

I do believe that it is not a very efficient way to solve your problem, but at least, it is a good place to start.

我确实相信这不是解决您问题的非常有效的方法,但至少,这是一个很好的起点。

回答by Adam Driscoll

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;
       }
  }
}

Maybe something like that....

也许是这样的......

回答by Steve Cooper

The answer is this; it searches through the entire application domain -- that is, every assembly currently loaded by your application.

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

/// <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));
}

It is used like this;

它是这样使用的;

var disposableTypes =  TypesImplementingInterface(typeof(IDisposable));

You may also want this function to find actual concrete types -- i.e., filtering out abstracts, interfaces, and generic type definitions.

您可能还希望该函数找到实际的具体类型——即过滤掉抽象、接口和泛型类型定义。

public static bool IsRealClass(Type testType)
{
    return testType.IsAbstract == false
         && testType.IsGenericTypeDefinition == false
         && testType.IsInterface == false;
}

回答by Hallgrim

You have to loop over all assemblies that you are interested in. From the assembly you can get all the types it defines. Note that when you do AppDomain.CurrentDomain.Assemblies you only get the assemblies that are loaded. Assemblies are not loaded until they are needed, so that means that you have to explicitly load the assemblies before you start searching.

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

回答by Sam

Here are some Typeextension methods that may be useful for this, as suggested by Simon Farrow. This code is just a restructuring of the accepted answer.

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

Code

代码

/// <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);
}

Examples

例子

To get the instantiable implementors in the calling assembly:

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

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

To get the implementors in the current AppDomain:

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

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