使用反射,如何使用最少的代碼得到使用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; }
我認可,它不漂亮。