什麼是對.NET異常捕獲意外地空
會的解釋,我有一個很奇怪的問題,即捕捉到的異常是空見下文。
該代碼使用MEF並努力報告組合錯誤。使用調試器,我可以看到拋出的異常(一個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;
}
我用註釋代替的代碼是非常簡單的代碼來格式化錯誤消息。沒有什麼奇怪的。
我試圖修改代碼以發現可能有什麼樣的影響:
- 如果我刪除了第一個catch塊(
ReflectionTypeLoadException
)夾在最終catch塊異常不再爲空。 - 如果我在第一個catch塊中捕獲到另一個異常類型,則在最終catch塊中捕獲的異常不再爲空。
- 如果我爲
InvalidOperationException
添加一個catch塊作爲第一個catch塊,那麼在該塊中捕獲的異常不爲null。 - 如果我在兩個catch塊之間爲
InvalidOperationException
添加一個catch塊,那麼在該塊中捕獲的異常爲null。
該項目使用Code Contracts並且編譯器生成的代碼被後處理以檢查合同。不幸的是,我還沒有想出一種方法來擺脫這個測試的目的,而無需對項目進行大手術。
我目前的解決方法是不捕獲ReflectionTypeLoadException
,而是在一般異常處理程序中分支ex
類型。
對這種「不可能」的行爲有什麼解釋?什麼是ReflectionTypeLoadException
catch塊?
令人尷尬的是,該異常不爲空,並且它不能爲null,符合C#標準15.9.5。
但是,在項目can mess up the display of local variables in the debugger中使用代碼契約,因爲編譯器生成的IL代碼可以由代碼契約重寫,因此最終的IL與調試信息略有不同步。在我的情況下,ex
變量顯示爲空,即使它不是。在應用程序終止之前發生的錯誤報告的不幸本質意味着我相信錯誤報告不會因爲ex
爲空而被調用,並且ex.Message
會在我的catch塊中拋出NullReferenceException
。使用調試器,我能夠「驗證」ex
爲空,除非它實際上不爲空。
我的混淆因爲ReflectionTypeLoadException
的catch塊似乎影響調試器顯示問題而變得更加複雜。
感謝所有回覆。
實際上是否有拋出的'ReflectionTypeLoadException'在任何地方? – Jaymz 2011-04-13 14:30:53
只是一個筆記,但你可以處理不同類型的異常,或者你只是報告相同的每個?如果這是通用報告,並且您無法處理異常,那麼我不確定您是否需要對捕獲進行範圍調整。 – 2011-04-13 14:35:38
當您爲InvalidOperationExecption添加捕獲時會發生什麼? – 2011-04-13 14:37:03