【发布时间】:2008-11-19 16:43:31
【问题描述】:
我们需要获取实现给定接口的所有对象实例 - 我们可以这样做吗?如果可以,如何做?
【问题讨论】:
标签: c# reflection
我们需要获取实现给定接口的所有对象实例 - 我们可以这样做吗?如果可以,如何做?
【问题讨论】:
标签: c# reflection
如果您需要实现特定接口的所有类型的实例(示例),您可以遍历所有类型,检查接口并在找到匹配项时创建实例。
这里有一些伪代码,看起来非常像 C#,甚至可以编译并返回你需要的东西。如果不出意外,它将为您指明正确的方向:
public static IEnumerable<T> GetInstancesOfImplementingTypes<T>()
{
AppDomain app = AppDomain.CurrentDomain;
Assembly[] ass = app.GetAssemblies();
Type[] types;
Type targetType = typeof(T);
foreach (Assembly a in ass)
{
types = a.GetTypes();
foreach (Type t in types)
{
if (t.IsInterface) continue;
if (t.IsAbstract) continue;
foreach (Type iface in t.GetInterfaces())
{
if (!iface.Equals(targetType)) continue;
yield return (T) Activator.CreateInstance(t);
break;
}
}
}
}
现在,如果您正在谈论遍历堆并返回实现特定类型的所有对象的先前实例化实例,那么祝您好运,因为 .Net 运行时不存储此信息(可由调试器/分析器计算通过检查堆/堆栈)。
根据您认为需要这样做的原因,可能有更好的方法。
【讨论】:
我不相信有办法...您必须能够遍历堆并检查那里的每个对象,或者遍历应用程序进程空间中每个活动线程的堆栈,检查每个堆栈每个线程上的引用变量...
另一种方式,(我猜你做不到)是拦截所有对象创建活动(使用容器方法)并保留应用程序中所有对象的列表......
【讨论】:
一个对象的所有实例,还是所有类型?
获取对象的所有实例几乎是不可能的,并且会涉及有关通过管理内存进行扫描的非公开信息。
获取实现给定接口的所有类型是可行的 --- 在给定域内。 (即,您可以找到在实现特定接口的程序集中定义的所有类型)
【讨论】:
如果实现指定接口的类是你的,那么你可以在实例化时实现一个弱引用列表。
【讨论】:
IEnumerable<Type> GetAllTypesThatImplementInterface<T>()
{
var @interface = typeof (T);
return @interface.IsInterface
? AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly => assembly.GetTypes())
.Where(type => !type.IsInterface
&& !type.IsAbstract
&& type.GetInterfaces().Contains(@interface))
: new Type[] {};
}
【讨论】: