[英]Proper way to rethrow an exception
我在c#中具有以下方法:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
}
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception)
{
//??
}
}
void Method3()
{
//Do something
if(error)
{
throw(new Method3Exception("error"));
}
}
Method3將由不同的方法調用,並且它返回Method3Exception,我需要將異常從Method2拋出到Method1,但是我不想在Method1上捕獲Method3Exception。 最好的方法是什么?
有什么建議么
術語(重新)拋出通常是指將異常返回給調用方,以保留堆棧跟蹤(其中包含異常發生的確切位置)。 可以使用throw;
來完成throw;
沒有指定與throw ex
相反的異常操作數:
try
{
Method3();
}
catch(Method3Exception)
{
throw;
}
但是 ,如果您只想在該方法中添加一個之前沒有任何內容的throw。 這是沒有用的,只需刪除try..catch,異常將傳播到調用方,這是默認行為。
文件 :
在catch塊中可以使用throw語句重新拋出catch塊捕獲的異常。 在這種情況下,throw語句不采用異常操作數。
重新拋出異常的另一種方法(使用throw;
如其他答案所述)是將異常包裝在內部異常中。 如MSDN中所述 ,所有自定義異常都應至少具有四個構造函數,其中之一是
public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }
因此,如果您所有的自定義異常都是這樣,則可以將Method3
的異常Method3
為內部異常:
void Method2()
{
if(error)
{
throw(new Method2Exception("error"));
}
//Do something and call method3
try
{
Method3();
}
catch(Method3Exception exc)
{
throw new Method2Exception("error", exc); // exc is passed as inner exception
}
}
然后,如果要檢查Method1
的內部異常, Method1
可以使用屬性InnerException
:
void Method1()
{
try
{
Method2();
}
catch(Method2Exception ex)
{
if(ex.InnerException != null)
{
var message = ex.InnerException.Message;
// Do what you need with the message
}
}
}
在Method2
,可以引發一個新的Method2Exception
,並將現有的Method3Exception
作為其InnerException
:
try
{
Method3();
}
catch(Method3Exception method3Exception)
{
throw new Method2Exception("Message", method3Exception);
}
然后,您可以捕獲上面的Method2Exception
:
try
{
Method2();
}
catch(Method2Exception ex)
{
//Log error
}
默認情況下例外是氣泡。 例如,
void FirstMethod()
{
int a = 0;
int b = 10;
int c = b / a;
}
void SecondMethod()
{
FirstMethod();
}
void ThirdMethod()
{
SecondMethod();
}
void FourthMethod()
{
try
{
ThirdMethod();
}
catch (DivideByZeroException ex)
{
// Handle error
}
}
異常將在FirstMethod中發生,並且會上升,並將在ForurthMethod中進行處理 。 例如,如果要在ThirdMethod中 記錄異常,但仍希望在ThirdMethod中處理異常,則必須選擇:
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex)
{
// Log the error
throw; // Throw exception without affecting StackTrace
}
}
在C#6.0之后,您可以通過使用異常過濾器輕松地做到這一點。 創建一個返回false的記錄器方法。
bool Log(Exception ex)
{
// Log the error
return false;
}
在第三個方法中添加異常過濾器 :
void ThirdMethod()
{
try
{
SecondMethod();
}
catch (Exception ex) when(Log(ex))
{
// Debugger won't reach here
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.