如何通过C#中的反射获得接口的所有实现?
答案 0 :(得分:58)
答案是这样的;它搜索整个应用程序域 - 即应用程序当前加载的每个程序集。
/// <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));
}
像这样使用;
var disposableTypes = TypesImplementingInterface(typeof(IDisposable));
您可能还希望此函数查找实际的具体类型 - 即过滤掉摘要,接口和泛型类型定义。
public static bool IsRealClass(Type testType)
{
return testType.IsAbstract == false
&& testType.IsGenericTypeDefinition == false
&& testType.IsInterface == false;
}
答案 1 :(得分:5)
查看Assembly.GetTypes()
方法。它返回可在程序集中找到的所有类型。您所要做的就是遍历每个返回的类型并检查它是否实现了必要的接口。
关于这样做的方法是使用Type.IsAssignableFrom
方法。
这是一个例子。 myInterface
是您要搜索的实现的接口。
Assembly myAssembly;
Type myInterface;
foreach (Type type in myAssembly.GetTypes())
{
if (myInterface.IsAssignableFrom(type))
Console.WriteLine(type.FullName);
}
我确实认为这不是解决问题的有效方法,但至少,这是一个很好的起点。
答案 2 :(得分:4)
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;
}
}
}
也许是这样的......
答案 3 :(得分:3)
根据Type
的建议,以下是一些可能对此有用的Simon Farrow扩展方法。此代码只是对已接受答案的重组。
/// <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);
}
获取调用程序集中的可实例化实现者:
var callingAssembly = Assembly.GetCallingAssembly();
var httpModules = typeof(IHttpModule).GetInstantiableImplementors(callingAssembly);
要在当前AppDomain中获取实现者:
var appDomainAssemblies = AppDomain.CurrentDomain.GetAssemblies();
var httpModules = typeof(IHttpModule).GetImplementors(appDomainAssemblies);
答案 4 :(得分:1)
你的意思是Type实现的所有接口吗?
像这样:
ObjX foo = new ObjX();
Type tFoo = foo.GetType();
Type[] tFooInterfaces = tFoo.GetInterfaces();
foreach(Type tInterface in tFooInterfaces)
{
// do something with it
}
希望能有所帮助。
答案 5 :(得分:1)
您必须遍历您感兴趣的所有程序集。从程序集中,您可以获得它定义的所有类型。请注意,当您执行AppDomain.CurrentDomain.Assemblies时,只能获取已加载的程序集。在需要之前不会加载程序集,因此这意味着您必须在开始搜索之前显式加载程序集。