捕获的.NETexception是意外的空

请参阅下面的说明正在发生的事情

我有一个非常奇怪的问题,捕获的exception是null。

代码使用MEF并尽力报告组合错误。 使用debugging器,我可以看到抛出的exception( InvalidOperationException ),但是当它被下面的代码中的最后一个catch块捕获时, exvariables为null。 在debugging器和正常执行代码时都是如此。

 static T ResolveWithErrorHandling<T>() where T : class { try { IocContainer.Compose(Settings.Default.IocConfiguration); return IocContainer.Resolve<T>(); } catch (ReflectionTypeLoadException ex) { // ... special error reporting for ReflectionTypeLoadException } catch (Exception ex) { // ex is null - that should not be possible! // ... general error reporting for other exception types } return null; } 

我已经用注释replace的代码是非常简单的代码来格式化错误消息。 没有什么奇怪的。

我试图改变代码来发现可能有什么效果:

  • 如果我删除第一个catch块( ReflectionTypeLoadException ),则在最后的catch块中捕获的exception不再为空。
  • 如果我在第一个catch块中捕获另一个exceptiontypes,那么在最后的catch块中捕获的exception不再为空。
  • 如果为InvalidOperationException添加一个catch块作为第一个catch块,那么该块中捕获的exception不为空。
  • 如果为两个catch块之间的InvalidOperationException添加一个catch块,则在该块中捕获的exception为null。

该项目使用代码合同 ,编译器生成的代码被后处理以检查合同。 不幸的是,我还没有想出一个方法来摆脱这个testing的目的,而不是在项目上进行大手术。

我目前的解决方法是不捕获ReflectionTypeLoadException ,而是在一般的exception处理程序的extypes分支。

这个“不可能”的行为有什么解释? 什么是ReflectionTypeLoadException catch块?


令人尴尬的是,这个exception不是null,并且它不能为空,即每个C#标准15.9.5。

但是,在项目中使用代码合同可能会在debugging器中显示局部variables,因为编译器生成的IL代码可以通过代码合同重写,因此最终的IL与debugging信息略有不同步。 在我的情况下, exvariables显示为空即使它不是。 在应用程序终止之前发生错误报告的不幸本质意味着我相信错误报告不会被称为ex和null, ex.Message在我的catch块中抛出一个NullReferenceException 。 使用debugging器,我能够“validation” ex是空的,除了它实际上不是空的。

由于ReflectionTypeLoadException的catch块似乎影响了debugging器的显示问题,所以我的困惑更加复杂了。

感谢所有的回应。

刚刚遇到了同样的问题。 我终于发现,我用同样的名字find了不同的例外,就像你所做的那样:

 catch (ReflectionTypeLoadException ex) { // ... } catch (Exception ex) { // ex is not null! // ... } 

两者都被命名为“前”。 改变这两个名字之一为我解决了这个问题,如:

 catch (ReflectionTypeLoadException reflectionEx) { // ... } catch (Exception ex) { // ex is null - that should not be possible! // ... } 

我遇到了同样的问题。 在我的情况下,重命名exceptionvariables(例如ex => ex1)允许我捕捉任何exception…

你应该检查是否在某个时候,IocContainer捕获一个Exception ex抛出ex.InnerException而不检查它是否为空。

C#高兴地接受throw null ,并在catch (Exception)

我遇到了同样的问题。 即使正确的exceptiontypes(UpdateException)被捕获,在debugging器中查看exception也是null。 我可以通过打开例外助手来查看exception。

只要我closures“执行运行时合同检查”捕获不再为空的exception。 我一直在积极地使用代码合同来进行一年的工作,在我最近在这个特定的项目中开始使用EF 4.1之前,还没有看到这个问题 – 但是我不知道EF是否是一个控制variables, 。

这个exception实际上不是null,这是debugging器的问题。 代码契约(ccrewrite)改变了IL操作码,扰乱了debugging器,因为leave.s操作码被转换为离开操作码。 这两个操作码有不同的大小和指令地址的变化,这就是为什么当exception名称相同时debugging器会丢失。

您可以在debugging器中使用$exception来解决问题。

我也有同样的情况。 这恰好是Eclipsedebugging器的一个错误。 (真的,这种情况只能是一些debugging器错误的结果。)

Eclipse重新启动就足够了 – 运行时exception变得正常,不为空。 其他debugging器可能不那么好。