我遇到了一个使用.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上其他相关问题的已接受解决方案,但没有成功,请不要建议我跟随它们)。