使用反射,如何使用最少的代码得到使用C#3.0 / .NET 3.5实现接口的全部类型,并最大限度地减小迭代? oop
这就是我想要重写的内容: this
foreach (Type t in this.GetType().Assembly.GetTypes()) if (t is IMyInterface) ; //do stuff
这里的其余答案使用IsAssignableFrom
。 您还能够使用FindInterfaces
从System
命名空间,如所描述这里 。 spa
下面是一个示例,它检查当前正在执行的程序集文件夹中的全部程序集,查找实现某个接口的类(为清楚起见,避免使用LINQ)。 .net
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(); }
若是要匹配多个接口,能够设置接口列表。 code
这对我有用。 它循环遍历类并检查它们是否来自myInterface orm
foreach (Type mytype in System.Reflection.Assembly.GetExecutingAssembly().GetTypes() .Where(mytype => mytype .GetInterfaces().Contains(typeof(myInterface)))) { //do stuff }
循环遍历全部加载的程序集,遍历全部类型,并检查它们是否实现了接口。 接口
就像是: get
Type ti = typeof(IYourInterface); foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) { foreach (Type t in asm.GetTypes()) { if (ti.IsAssignableFrom(t)) { // here's your type in t } } }
个人将是这个在c#3.0 :) string
var type = typeof(IMyInterface); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p));
基本上,迭代次数最少的是: it
loop assemblies loop types see if implemented.
编辑:我刚刚看到编辑,以澄清原始问题是减小迭代/代码,这一切都很好,做为一个练习,但在现实世界的状况下,你将须要最快的实现,不管如何底层LINQ看起来有多酷。
这是个人Utils方法,用于迭代加载的类型。 它处理常规类和接口,若是您在本身的/第三方代码库中寻找实现,则excludeSystemTypes选项能够大大加快速度。
public static List<Type> GetSubclassesOf(this Type type, bool excludeSystemTypes) { List<Type> list = new List<Type>(); IEnumerator enumerator = Thread.GetDomain().GetAssemblies().GetEnumerator(); while (enumerator.MoveNext()) { try { Type[] types = ((Assembly) enumerator.Current).GetTypes(); if (!excludeSystemTypes || (excludeSystemTypes && !((Assembly) enumerator.Current).FullName.StartsWith("System."))) { IEnumerator enumerator2 = types.GetEnumerator(); while (enumerator2.MoveNext()) { Type current = (Type) enumerator2.Current; if (type.IsInterface) { if (current.GetInterface(type.FullName) != null) { list.Add(current); } } else if (current.IsSubclassOf(type)) { list.Add(current); } } } } catch { } } return list; }
我认可,它不漂亮。