使用反射,我如何能得到所有类型的实现接口与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
当前回答
我在这里看到了太多过于复杂的答案,人们总是告诉我,我倾向于把事情复杂化。同样使用IsAssignableFrom方法来解决OP问题也是错误的!
下面是我的例子,它从应用程序域中选择所有程序集,然后它采用所有可用类型的平面列表,并检查每个类型的接口列表是否匹配:
public static IEnumerable<Type> GetImplementingTypes(this Type itype)
=> AppDomain.CurrentDomain.GetAssemblies().SelectMany(s => s.GetTypes())
.Where(t => t.GetInterfaces().Contains(itype));
其他回答
这对我很管用。它循环遍历这些类并检查它们是否派生自myInterface
foreach (Type mytype in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
.Where(mytype => mytype .GetInterfaces().Contains(typeof(myInterface)))) {
//do stuff
}
(就性能而言)做你想做的事情并不容易。
反射主要使用程序集和类型,因此您必须获取程序集的所有类型并查询它们以获得正确的接口。这里有一个例子:
Assembly asm = Assembly.Load("MyAssembly");
Type[] types = asm.GetTypes();
Type[] result = types.where(x => x.GetInterface("IMyInterface") != null);
这将为您提供在程序集MyAssembly中实现IMyInterface的所有类型
你可以使用一些LINQ来获取列表:
var types = from type in this.GetType().Assembly.GetTypes()
where type is ISomeInterface
select type;
但说真的,这样更有可读性吗?
在选择组装位置时就更好了。如果您知道所有实现的接口都在同一个Assembly.DefinedTypes中,则可以筛选大多数程序集。
// We get the assembly through the base class
var baseAssembly = typeof(baseClass).GetTypeInfo().Assembly;
// we filter the defined classes according to the interfaces they implement
var typeList = baseAssembly.DefinedTypes.Where(type => type.ImplementedInterfaces.Any(inter => inter == typeof(IMyInterface))).ToList();
文/詹·比尔金
我在linq-code中得到了异常,所以我这样做(没有复杂的扩展):
private static IList<Type> loadAllImplementingTypes(Type[] interfaces)
{
IList<Type> implementingTypes = new List<Type>();
// find all types
foreach (var interfaceType in interfaces)
foreach (var currentAsm in AppDomain.CurrentDomain.GetAssemblies())
try
{
foreach (var currentType in currentAsm.GetTypes())
if (interfaceType.IsAssignableFrom(currentType) && currentType.IsClass && !currentType.IsAbstract)
implementingTypes.Add(currentType);
}
catch { }
return implementingTypes;
}