使用反射,我如何能得到所有类型的实现接口与c# 3.0/。NET 3.5用最少的代码,最小化迭代?
这是我想重写的内容:
foreach (Type t in this.GetType().Assembly.GetTypes())
if (t is IMyInterface)
; //do stuff
使用反射,我如何能得到所有类型的实现接口与c# 3.0/。NET 3.5用最少的代码,最小化迭代?
这是我想重写的内容:
foreach (Type t in this.GetType().Assembly.GetTypes())
if (t is IMyInterface)
; //do stuff
当前回答
OfType Linq方法正好可以用于这种场景:
https://learn.microsoft.com/fr-fr/dotnet/api/system.linq.enumerable.oftype?view=netframework-4.8
其他回答
遍历所有加载的程序集,遍历它们的所有类型,并检查它们是否实现了接口。
喜欢的东西:
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:)
var type = typeof(IMyInterface);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p));
基本上,最少的迭代次数总是:
loop assemblies
loop types
see if implemented.
如果它能帮助任何人,这是我正在使用的使我的一些单元测试更容易:)
public static Type GetInterfacesImplementation(this Type type)
{
return type.Assembly.GetTypes()
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface)
.SingleOrDefault();
}
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));
}
编辑:我刚刚看到了编辑,澄清了最初的问题是为了减少迭代/代码,这作为一个练习是很好的,但在实际情况下,你会想要最快的实现,不管底层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;
}
我承认,这并不漂亮。