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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/302542/
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 22:20:51  来源:igfitidea点击:

How do I get all instances of all loaded types that implement a given interface?

c#reflection

提问by Simon

We need to get all the instances of objects that implement a given interface - can we do that, and if so how?

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

采纳答案by Charles Bretana

I don't believe there is a way... You would have to either be able to walk the Heap, and examine every object there, or walk the stack of every active thread in the application process space, examining every stack reference variable on every thread...

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

The other way, (I am guessing you can't do) is intercept all Object creation activities (using a container approach) and keep a list of all objects in your application...

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

回答by Charles Bretana

If you need instances (samples) of all types implementing particular interface you can go through all types, check for interface and create instance if match found.

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

Here's some pseudocode that looks remarkably like C# and may even compile and return what you need. If nothing else, it will point you in the correct direction:

下面是一些看起来非常像 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;
            }
        }
    }
}

Now, if you're talking about walking the heap and returning previously instantiated instances of all objects that implement a particular type, good luck on that as this information is not stored by .Net runtime (can be computed by debugers/profilers by examining heap/stack so).

现在,如果您正在谈论遍历堆并返回实现特定类型的所有对象的先前实例化实例,那么祝您好运,因为 .Net 运行时不存储此信息(可以由调试器/分析器通过检查堆来计算) /堆栈所以)。

Depending on the reason why you think you need to do that there are probably better ways of going about it.

根据您认为需要这样做的原因,可能有更好的方法。

回答by James Curran

All instances of an Object, or all Types?

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

Getting all instances of an Object would be pretty close to impossible, and would involve non-public information about the scan through management memory.

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

Getting all types that implement a given interface is doable --- within a given domain. (ie, you can find all type defined within an assembly that implement a particular interface)

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

  • Load the Assembly
  • Iterate through it's types (call asm.GetTypes())
  • Check typeof(IMyInterface).IsAssignibleFrom(testType)
  • 加载程序集
  • 遍历它的类型(调用 asm.GetTypes())
  • 检查 typeof(IMyInterface).IsAssignibleFrom(testType)

回答by smartcaveman

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

回答by user1191352

If the classes implementing the specified interface are yours then you can implement a list of weak references upon instantiation.

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