在.NET中捕获异常时,可以根据需要使用尽可能多的特定于类型的异常块。但我通常会尝试至少有一个“常规”异常catch块。但有没有办法获得抛出通用异常处理程序捕获的“真正”异常的类型,可能使用反射?
例如,如果我有
Catch ex As System.ServiceModel.FaultException(Of InvalidUser)
ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException(Of SQLExceptions)
ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException(Of DataNullReference)
ProcessModuleLoadException(Me, ex)
Catch ex As System.ServiceModel.FaultException
ProcessModuleLoadException(Me, ex)
Catch ex As Exception
ProcessModuleLoadException(Me, ex)
(我已将它们分解为调试,即使我对每个例外做同样的事情)。
简而言之,在“Catch ex As System.ServiceModel.FaultException”中,我想检查“ex”并获取异常的基本“真实”类型,作为一种类型(主要用于调试,所以我可以添加另一个catch块)或作为字符串(用于记录)。
但是,在Catch块中,“ex”已被强制转换为它的父类,因此任何原始属性和有关原始异常的信息似乎都会丢失。
建议?
答案 0 :(得分:15)
即使已将Exception
强制转换为其父类,您仍然可以调用GetType
来获取其基础具体类型(请原谅我的C#):
try {
// Do stuff
}
catch(Exception ex) {
Type exceptionType = ex.GetType();
}
如果这仅用于诊断目的,您可以记录ex.ToString()
,默认情况下包括基础类型(除了堆栈跟踪等),如下所示:
System.ArgumentException: lastName
at Tests.Program.Main(String[] args) in ...\Program.cs:line 22
答案 1 :(得分:2)
.GetType
仍将返回其实际类型。
答案 2 :(得分:2)
这只是对杰夫回答的一点修改:
我正在寻找像Chris所描述的那样的内容,特别是我希望在它被一些通用异常再次抛出之后处理原始异常,并且只有一个我可以为所有入口点调用的处理程序。并且由于重新抛出异常将使用自己的异常类型包装它,我们需要添加循环以完成内部异常,并检查抛出的第一个异常。
所以这是我最终得到的代码:
Public Sub HandelException(myEx As Exception)
Try
Dim InnerEx As Exception = myEx
Do Until InnerEx.InnerException Is Nothing
InnerEx = InnerEx.InnerException
Loop
If InnerEx.GetType = GetType(Exception1) Then
'Handle exception type 1
ElseIf InnerEx.GetType = GetType(Exception2) Then
'Handle exception type 2
ElseIf InnerEx.GetType = GetType(Exception3) Then
'Handle exception type 3
ElseIf InnerEx.GetType = GetType(Exception4) Then
'Handle exception type 4
ElseIf InnerEx.GetType = GetType(Exception) Then
'Handle generic system exception
End If
Catch ex As Exception
'Handel unlikely exception in exception handler LOL.
End Try
End Sub
这样做的好处是,您可以在整个程序中处理各种异常类型,包含大量处理代码,但您可以在一个地方处理它们。
我知道这个回答对于这个问题来说有点晚了,但我想我会分享,如果可能是为了帮助任何人寻找我想要的东西。
答案 3 :(得分:0)
如何将其作为通用系统异常捕获,然后使用“is”术语来测试实际类型?
try
{
// Something
}
catch(Exception ex)
{
// Single catch block - catches as generic system exception
if(ex is FaultException) {
//Process as FaultEx
}
if(ex is ArithmeticException) {
//Process as ArithEx
}
if(ex is ArgumentException) {
//Process as ArgEx
}
}
finally
{
//Cleanup
}