为什么Type.IsAssignableFrom方法在这里返回false?

时间:2016-03-15 12:43:46

标签: c# reflection interface

我使用.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的其他相关问题的公认解决方案没有成功,所以请不要建议我遵循它们。)

1 个答案:

答案 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 :-)