我使用.NET反射遇到了一个奇怪的问题。如果你知道为什么会这样,请告诉我。
要求:
我需要在实现特定接口的特定命名空间中生成每个类的实例集合。
原始解决方案:
List<IReport> allReportTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
t => !t.IsAbstract && t.IsClass && t.IsAssignableFrom(typeof(IReport)) && t.Namespace
== @namespace).Select(t => Activator.CreateInstance(t) as IReport).ToList();
这个原始解决方案什么也没有回来,我的问题是为什么?每个类都正确实现了IReport
接口,并已在相关的命名空间中声明。通过删除对IsAssignableFrom
:
List<IReport> allReportTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
t => !t.IsAbstract && t.IsClass && t.Namespace == @namespace).Select(t =>
Activator.CreateInstance(t) as IReport).ToList();
这将返回我想要的类的实例,但不检查所需的接口。请注意,Activator.CreateInstance
方法的结果已成功转换为IReport
接口,因此返回的类肯定会实现它。我继续解决这个问题,并设法在以下查询中提出满足我所有要求的解决方法。
工作解决方案
List<IReport> allReportTypes = Assembly.GetExecutingAssembly().GetTypes().Where(
t => !t.IsAbstract && t.IsClass && ((TypeInfo)(t)).ImplementedInterfaces.Contains(
typeof(IReport)) && t.Namespace == @namespace).Select(t => Activator.CreateInstance(t)
as IReport).ToList();
但是,我想知道为什么IsAssignableFrom
方法没有按照它所说的那样......或者MSDN。 (我也尝试过关于Stack Overflow的其他相关问题的公认解决方案没有成功,所以请不要建议我遵循它们。)
答案 0 :(得分:5)
此:
t.IsAssignableFrom(typeof(IReport))
错误...例如ReportClass
是否可以从IReport
分配?没有!在代码中:
IReport someReport = ...;
ReportClass cl = someReport; // Error!
正确的是:
typeof(IReport).IsAssignableFrom(t)
IReport
是否可以从具体类型t
分配?
ReportClass cl = ...
IReport inter = cl; // OK :-)