如何获取实现给定接口的所有已加载类型的所有实例?

时间:2008-11-19 16:43:32

标签: c# reflection

我们需要获得实现给定接口的所有对象实例 - 我们可以这样做吗,如果是这样的话?

5 个答案:

答案 0 :(得分:16)

如果您需要实现特定接口的所有类型的实例(示例),您可以浏览所有类型,检查接口并在找到匹配项时创建实例。

这里有一些看起来非常像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运行时不存储此信息(可以通过debugers / profilers计算)通过检查堆/堆栈)。

根据你认为你需要这样做的原因,可能有更好的方法来实现它。

答案 1 :(得分:6)

我不相信有一种方法......你必须要么能够遍历堆,并检查那里的每个对象,或者在应用程序进程空间中遍历每个活动线程的堆栈,检查每个堆栈每个线程上的引用变量......

另一种方式,(我猜你做不到)是拦截所有对象创建活动(使用容器方法)并保留应用程序中所有对象的列表...

答案 2 :(得分:4)

对象的所有实例,还是所有类型?

获取对象的所有实例几乎是不可能的,并且涉及有关扫描管理内存的非公开信息。

在给定的域内获取实现给定接口的所有类型是可行的。 (即,您可以找到实现特定接口的程序集中定义的所有类型)

  • 加载程序集
  • 迭代它的类型(调用asm.GetTypes())
  • 检查typeof(IMyInterface).IsAssignibleFrom(testType)

答案 3 :(得分:2)

如果实现指定接口的类是您的,那么您可以在实例化时实现弱引用列表。

答案 4 :(得分:1)

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[] {};
}