Assembly.GetTypes()抛出异常

时间:2012-08-11 14:11:25

标签: c# .net reflection

程序集GetTypes()在幕后做了什么?假设已将程序集加载到AppDomain,它是否还需要从物理DLL中读取?汇编清单的作用是什么?

像这样迭代整个程序集:

AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes()) 

我偶尔会收到以下错误:

 Could not load file or assembly 

这告诉我,因为程序集被加载到AppDomain中,所以它不一定完全加载到内存中。有时它仍然需要返回文件。

我的问题:

  1. 为什么这样做?
  2. 如何检测这些半装配件?

2 个答案:

答案 0 :(得分:33)

从程序集中获取类型可能需要加载其他程序集,这很可能是导致错误的原因;无法加载从属程序集。但是,.NET程序集可能由不同文件中的多个模块构建,因此如果您有multifile assembly并且一个或多个文件丢失或损坏,我相信您也可能会遇到此问题。

与错误相关联,您应该获得有关无法加载的特定程序集的更多信息。

如果您只想加载程序集中的可加载类型列表,可以使用这样的扩展方法:

public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
    if (assembly == null) throw new ArgumentNullException(nameof(assembly));
    try
    {
        return assembly.GetTypes();
    }
    catch (ReflectionTypeLoadException e)
    {
        return e.Types.Where(t => t != null);
    }
}

(资料来源:Get All Types in an Assembly

答案 1 :(得分:2)

在幕后,GetType方法返回存储在指定对象的类型对象指针成员中的地址(当对象存储在堆中时,此信息与其他几个像Sync Block Index一起存储)。这是GetType方法返回任何对象的真实类型的方式。程序集可能依赖于必须加载的其他程序集。除非应用程序要求,否则它不会被JIT加载。所以,是的,它要求装配在任何时候都是物理可用的。