任何“安全”的方法调用assembly.GetTypes()

本文关键字:assembly GetTypes 调用 方法 安全 任何 | 更新日期: 2023-09-27 17:50:13

我已经到处找了,但是我不能想出一个解决办法。

我需要从程序集获得所有接口类型,代码如下:

IEnumerable<Type> interfaces = _assembly.GetTypes().Where(x => x.IsInterface);

问题是,对于某些程序集,我遇到以下错误:

无法加载一个或多个请求的类型。检索LoaderExceptions属性获取更多信息信息。

我完全清楚为什么会发生这种情况(依赖程序集没有加载),以及如果我想对特定的程序集进行故障排除,它可以如何工作。在我的例子中,我不知道前面的程序集(用户将选择它)。

我想知道的是,是否有任何方法允许代码继续过去的任何类型,无法检索,仍然拉那些不失败。

任何“安全”的方法调用assembly.GetTypes()

看起来这是一个令人烦恼的API,异常无法避免(据我所知)。

试试这样写:

IEnumerable<Type> interfaces;
try
{
    interfaces = _assembly.GetTypes().Where(x => x.IsInterface);
}
catch (ReflectionTypeLoadException ex)
{
    interfaces = ex.Types.Where(x => x != null && x.IsInterface);
}

实际上,这是如此丑陋,我可能会把它藏在某个地方。这一定是。net框架中一个非常老的部分,因为我很确定他们现在不会这样设计它。

private static IEnumerable<Type> GetTypesSafely(Assembly assembly)
{
    try
    {
        return assembly.GetTypes();
    }
    catch(ReflectionTypeLoadException ex)
    {
        return ex.Types.Where(x => x != null);
    }
}
...
IEnumberable<Type> interfaces = GetTypesSafely(_assembly).Where(x => x.IsInterface);

如果您认为您将经常这样做,那么扩展方法可能更合适。

在替代lambda表达式并捕获异常的另一个方法中处理异常。您还可以将异常积累在一些全局对象中,以便稍后进行检查。

IEnumerable<Type> interfaces = _assembly.GetTypes().Where(IsInterface);
List<string> Messages = new List<string>();
private bool IsInterface(Type x)
{
    try { return x.IsInterface; }
    catch (Exception e)
    {
        Messages.Add(e.Message);
    }
    return false;
}