捕获的.NET异常意外地为空

Mar*_*age 37 c# exception-handling mef code-contracts

请参阅下文,了解正在进行的操作

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

该代码使用MEF并努力报告组合错误.使用调试器我可以看到抛出异常(a InvalidOperationException)但是当它被下面代码中的最后一个catch块捕获时,ex变量为null.在调试器和正常执行代码时都是如此.

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;
}
Run Code Online (Sandbox Code Playgroud)

我用注释替换的代码是格式化错误消息的非常简单的代码.那里没什么奇怪的.

我试图改变代码以发现可能产生的影响:

  • 如果我删除第一个catch块(ReflectionTypeLoadException),则最终catch块中捕获的异常不再为null.
  • 如果我在第一个catch块中捕获另一个异常类型,则最终catch块中捕获的异常不再为null.
  • 如果我InvalidOperationException为第一个catch块添加一个catch块,则该块中捕获的异常不为null.
  • 如果我InvalidOperationException在两个catch块之间添加一个catch块,则该块中捕获的异常为null.

该项目使用代码契约,并对编译器生成的代码进行后处理以检查合同.不幸的是,我没有找到一种方法来摆脱测试目的,而不对项目进行大手术.

我目前的解决方法是不捕获ReflectionTypeLoadException并改为分支ex一般异常处理程序中的类型.

对这种"不可能"的行为有什么解释?ReflectionTypeLoadExceptioncatch块有什么用?


令人尴尬的是,异常不为空,并且根据C#标准15.9.5不能为空.

但是,在项目中使用代码约定会破坏调试器中局部变量的显示,因为编译器生成的IL代码可以通过代码约定重写,因此最终的IL与调试信息稍微不同步.在我的情况下,ex变量显示为null,即使它不是.在应用程序终止之前发生的错误报告的不幸性质意味着我认为错误报告不会因为ex为空并且在我的catch块中ex.Message抛出而被调用NullReferenceException.使用调试器我能够"验证" ex为null,除了它实际上不是null.

由于catch块ReflectionTypeLoadException似乎影响调试器显示问题,我的困惑更加复杂.

感谢所有回复的人.

Gui*_*ten 13

刚遇到同样的问题.我终于发现我用同样的名字捕获了不同的异常,就像你做的那样:

catch (ReflectionTypeLoadException ex)
{
    // ... 
}
catch (Exception ex)
{
    // ex is not null!
    // ...
}
Run Code Online (Sandbox Code Playgroud)

两者都被命名为"前".更改其中一个名称可以解决这个问题,例如:

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


小智 5

我遇到了同样的问题.在我的情况下重命名异常变量(例如ex => ex1)允许我捕获任何异常......