任何“安全”的方法调用assembly.GetTypes()
本文关键字:assembly GetTypes 调用 方法 安全 任何 | 更新日期: 2023-09-27 17:50:13
我已经到处找了,但是我不能想出一个解决办法。
我需要从程序集获得所有接口类型,代码如下:
IEnumerable<Type> interfaces = _assembly.GetTypes().Where(x => x.IsInterface);
问题是,对于某些程序集,我遇到以下错误:
无法加载一个或多个请求的类型。检索LoaderExceptions属性获取更多信息信息。
我完全清楚为什么会发生这种情况(依赖程序集没有加载),以及如果我想对特定的程序集进行故障排除,它可以如何工作。在我的例子中,我不知道前面的程序集(用户将选择它)。
我想知道的是,是否有任何方法允许代码继续过去的任何类型,无法检索,仍然拉那些不失败。
看起来这是一个令人烦恼的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;
}