调用 Assembly.GetTypes() 时如何防止 ReflectionTypeLoadException
我正在尝试使用类似于以下的代码扫描程序集以查找实现特定接口的类型:
public List<Type> FindTypesImplementing<T>(string assemblyPath)
{
var matchingTypes = new List<Type>();
var asm = Assembly.LoadFrom(assemblyPath);
foreach (var t in asm.GetTypes())
{
if (typeof(T).IsAssignableFrom(t))
matchingTypes.Add(t);
}
return matchingTypes;
}
我的问题是,在调用 asm.GetTypes()
时,我收到 ReflectionTypeLoadException
在某些情况下,例如,如果程序集包含引用当前不可用的程序集的类型。
就我而言,我对导致问题的类型不感兴趣。我正在搜索的类型不需要不可用的程序集。
问题是:是否可以以某种方式跳过/忽略导致异常的类型,但仍然处理程序集中包含的其他类型?
I'm trying to scan an assembly for types implementing a specific interface using code similar to this:
public List<Type> FindTypesImplementing<T>(string assemblyPath)
{
var matchingTypes = new List<Type>();
var asm = Assembly.LoadFrom(assemblyPath);
foreach (var t in asm.GetTypes())
{
if (typeof(T).IsAssignableFrom(t))
matchingTypes.Add(t);
}
return matchingTypes;
}
My problem is, that I get a ReflectionTypeLoadException
when calling asm.GetTypes()
in some cases, e.g. if the assembly contains types referencing an assembly which is currently not available.
In my case, I'm not interested in the types which cause the problem. The types I'm searching for do not need the non-available assemblies.
The question is: is it possible to somehow skip/ignore the types which cause the exception but still process the other types contained in the assembly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
一种相当令人讨厌的方式是:
尽管如此,不得不这样做确实很烦人。您可以使用扩展方法来使其在“客户端”代码中变得更好:
您可能希望将
return
语句移出 catch 块 - 我本人不太热衷于它在那里,但它可能是最短的代码......One fairly nasty way would be:
It's definitely annoying to have to do this though. You could use an extension method to make it nicer in the "client" code:
You may well wish to move the
return
statement out of the catch block - I'm not terribly keen on it being there myself, but it probably is the shortest code...虽然在某些时候如果不收到 ReflectionTypeLoadException 就什么也做不了,但上面的答案是有限的,因为任何使用异常提供的类型的尝试仍然会出现导致类型加载失败的原始问题。
为了克服这个问题,以下代码将类型限制为位于程序集中的类型,并允许谓词进一步限制类型列表。
Whilst it appears that nothing can be done without receiving the ReflectionTypeLoadException at some point, the answers above are limited in that any attempt to utilise the types provided from the exception will still give issue with the original issue that caused the type to fail to load.
To overcome this the following code limits the types to those located within the assembly and allows a predicate to further restrict the list of types.
您是否考虑过 Assembly.ReflectionOnlyLoad ?考虑到您想要做什么,这可能就足够了。
Have you considered Assembly.ReflectionOnlyLoad ? Considering what you're trying to do, it might be enough.
Jon Skeet 的答案很好,但每次你仍然会遇到这个异常。要解决此问题,请使用以下代码片段并在 Visual Studio 的调试设置中打开“Just My Code”。
The answer from Jon Skeet works fine, but you still get this exception thrown in your face every time. To work around that use the following snippet and turn on "Just My Code" in the debugging settings of Visual Studio.
就我而言,同样的问题是由应用程序文件夹中存在不需要的程序集引起的。尝试清除 Bin 文件夹并重建应用程序。
In my case, the same problem was caused by the presence of unwanted assemblies in the application folder. Try to clear the Bin folder and rebuild the application.
当我的测试项目引用 nuget 包作为“传递依赖项”时,我就发生了这种情况,其版本与我的测试项目不同。我确保两者都安装了相同的软件包版本并且一切正常。
This happened to me when my test project was referencing a nuget package as a "transitive dependency" with a different version than my project-under-test. I ensured both had the same package versions installed and all was well.