【问题标题】:Assembly.GetTypes() throwing an exceptionAssembly.GetTypes() 抛出异常
【发布时间】:2015-11-01 22:39:00
【问题描述】:

大会GetTypes() 在幕后做了什么?假设程序集已加载到AppDomain,它还需要从物理 DLL 中读取吗?程序集清单有什么作用?

像这样遍历程序集:

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

我偶尔会收到以下错误:

 Could not load file or assembly 

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

我的问题:

  1. 为什么要这样做?
  2. 如何检测这些半加载程序集?

【问题讨论】:

    标签: c# .net reflection


    【解决方案1】:

    从程序集中获取类型可能需要加载其他程序集,因此这很可能是错误的原因;加载依赖程序集失败。然而,一个 .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

    【讨论】:

    • 这不适用于加载到经典 .net 运行时的核心 dll。您可以加载但不能浏览类型。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2013-05-24
      • 2011-05-30
      • 1970-01-01
      • 2011-02-25
      • 2012-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多