Getting all types that implement an interface

2020-01-22 11:47发布

Using reflection, how can I get all types that implement an interface with C# 3.0/.NET 3.5 with the least code, and minimizing iterations?

This is what I want to re-write:

foreach (Type t in this.GetType().Assembly.GetTypes())
    if (t is IMyInterface)
        ; //do stuff

14条回答
手持菜刀,她持情操
2楼-- · 2020-01-22 11:49

Other answer were not working with a generic interface.

This one does, just replace typeof(ISomeInterface) by typeof (T).

List<string> types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
            .Where(x => typeof(ISomeInterface).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
            .Select(x => x.Name).ToList();

So with

AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())

we get all the assemblies

!x.IsInterface && !x.IsAbstract

is used to exclude the interface and abstract ones and

.Select(x => x.Name).ToList();

to have them in a list.

查看更多
【Aperson】
3楼-- · 2020-01-22 11:50

Other answers here use IsAssignableFrom. You can also use FindInterfaces from the System namespace, as described here.

Here's an example that checks all assemblies in the currently executing assembly's folder, looking for classes that implement a certain interface (avoiding LINQ for clarity).

static void Main() {
    const string qualifiedInterfaceName = "Interfaces.IMyInterface";
    var interfaceFilter = new TypeFilter(InterfaceFilter);
    var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
    var di = new DirectoryInfo(path);
    foreach (var file in di.GetFiles("*.dll")) {
        try {
            var nextAssembly = Assembly.ReflectionOnlyLoadFrom(file.FullName);
            foreach (var type in nextAssembly.GetTypes()) {
                var myInterfaces = type.FindInterfaces(interfaceFilter, qualifiedInterfaceName);
                if (myInterfaces.Length > 0) {
                    // This class implements the interface
                }
            }
        } catch (BadImageFormatException) {
            // Not a .net assembly  - ignore
        }
    }
}

public static bool InterfaceFilter(Type typeObj, Object criteriaObj) {
    return typeObj.ToString() == criteriaObj.ToString();
}

You can set up a list of interfaces if you want to match more than one.

查看更多
地球回转人心会变
4楼-- · 2020-01-22 11:54
   public IList<T> GetClassByType<T>()
   {
        return AppDomain.CurrentDomain.GetAssemblies()
                          .SelectMany(s => s.GetTypes())
                          .ToList(p => typeof(T)
                          .IsAssignableFrom(p) && !p.IsAbstract && !p.IsInterface)
                          .SelectList(c => (T)Activator.CreateInstance(c));
   }
查看更多
地球回转人心会变
5楼-- · 2020-01-22 11:54

You could use some LINQ to get the list:

var types = from type in this.GetType().Assembly.GetTypes()
            where type is ISomeInterface
            select type;

But really, is that more readable?

查看更多
太酷不给撩
6楼-- · 2020-01-22 12:00

Mine would be this in c# 3.0 :)

var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
    .SelectMany(s => s.GetTypes())
    .Where(p => type.IsAssignableFrom(p));

Basically, the least amount of iterations will always be:

loop assemblies  
 loop types  
  see if implemented.
查看更多
Explosion°爆炸
7楼-- · 2020-01-22 12:01

To find all types in an assembly that implement IFoo interface:

var results = from type in someAssembly.GetTypes()
              where typeof(IFoo).IsAssignableFrom(type)
              select type;

Note that Ryan Rinaldi's suggestion was incorrect. It will return 0 types. You cannot write

where type is IFoo

because type is a System.Type instance, and will never be of type IFoo. Instead, you check to see if IFoo is assignable from the type. That will get your expected results.

Also, Adam Wright's suggestion, which is currently marked as the answer, is incorrect as well, and for the same reason. At runtime, you'll see 0 types come back, because all System.Type instances weren't IFoo implementors.

查看更多
登录 后发表回答