2011-04-12 56 views
19

我搜索了高和低,但我不能拿出一个解决方案。任何方式来“安全地”调用assembly.GetTypes()?

我需要让所有的接口类型从装配有这样的代码:

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

的问题是,对于某些组件我遇到了以下错误:

Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.

我m完全清楚为什么发生这种情况(依赖程序集未加载),以及如何解决特定程序集的故障。就我而言,我不知道装配前面(用户会选择它)。

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

回答

28

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

尝试这样:

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

UPDATE

其实,这是如此的丑陋我可能会隐藏在某个地方。这必须是.NET Framework的一个非常古老的部分,因为我很确定他们现在不会像这样设计它。

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

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

+0

将此用于特定目的(代码生成)。我不知道这个异常和Types属性。完善! – 2011-04-12 19:23:04

+0

非常感谢你!很长一段时间以来,我们一直在困扰着这个恼人的错误 – 2015-09-17 15:54:48

0

在另一个取代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; 
} 
相关问题