22

装配GetTypes()在幕后做什么?假设程序集已加载到AppDomain它是否仍需要从物理 DLL 中读取?装配清单做什么?

像这样遍历程序集:

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

我偶尔会收到以下错误:

 Could not load file or assembly 

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

我的问题:

  1. 为什么这样做?
  2. 我能做些什么来检测这些半加载的程序集?
4

2 回答 2

47

从程序集中获取类型可能需要加载其他程序集,因此这很可能是错误的原因;加载依赖程序集失败。然而,一个 .NET 程序集可能由不同文件中的多个模块构成,所以我相信如果您有一个多文件程序集并且一个或多个文件丢失或损坏,您也可能会遇到这个问题。

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

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

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);
    }
}

(来源:获取程序集中的所有类型

于 2012-08-11T14:14:40.693 回答
2

在幕后,GetType 方法返回存储在指定对象的类型对象指针成员中的地址(当对象存储在堆中时,此信息与同步块索引等其他信息一起存储)。这就是 GetType 方法返回任何对象的真实类型的方式。程序集可能依赖于必须加载的其他程序集。除非应用程序需要它,否则 JIT 不会加载它。所以,是的,它要求组件在物理上始终可用。

于 2012-08-11T14:52:37.470 回答